From 8f8eed75beb5bb9b66f2a87de856f2dbf11e6ffe Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期四, 20 十一月 2025 20:29:36 +0800
Subject: [PATCH] 修改
---
bin/xitongshezhi/ConfigSet.class | 0
bin/publicway/ProtocolParser01$FaultType.class | 0
bin/home/CardMachineUI.class | 0
bin/xitongshezhi/ConfigSet$2.class | 0
.classpath | 2
src/jiekou/TakeCardUtil.java | 184 ++
bin/publicway/SerialProtocolParser.class | 0
bin/chushihua/SlotManager.class | 0
src/jiekou/ReturnCardUtil.java | 230 ++
src/jiekou/TcpClientUtil.java | 595 +++++++
src/jiekou/HttpAPI.java | 129 +
.settings/org.eclipse.core.resources.prefs | 1
bin/xitongshezhi/lishijilu.class | 0
src/chushihua/SlotManager.java | 93
src/xitongshezhi/SystemDebugDialog.java | 10
bin/xitongshezhi/banbenguanli$1.class | 0
src/jiekou/TCPApi.java | 57
src/publicway/ProtocolParser01.java | 6
bin/publicway/ProtocolParser01$CardStatus.class | 0
bin/publicway/ProtocolParser01$WorkStatus.class | 0
bin/publicway/ProtocolParser01$ParseResultPool.class | 0
bin/publicway/ProtocolParser01$ParseResult.class | 0
bin/publicway/ProtocolParser01.class | 0
bin/chushihua/lunxun$PollingTask.class | 0
bin/chuankou/SerialPortService.class | 0
src/home/CardMachineUI.java | 36
bin/chuankou/SerialPortConnectionDialog.class | 0
src/jiekou/lunxunkazhuangtai.java | 174 ++
bin/home/CardMachineUI$1.class | 0
bin/xitongshezhi/ConfigSet$MenuItemListener.class | 0
src/chushihua/lunxunzaixian.java | 492 ++++++
bin/xitongshezhi/lishijilu$1.class | 0
src/xitongshezhi/lishijilu.java | 699 ++------
src/xitongshezhi/Dingshidialog.java | 260 +++
src/home/Homein.java | 14
src/jiekou/TakeCardSuccessUtil.java | 171 ++
src/chuankou/SerialPortService.java | 3
log.properties | 1
src/xitongshezhi/ConfigSet.java | 7
bin/xitongshezhi/ConfigSet$1.class | 0
src/xitongshezhi/banbenguanli.java | 1317 ++++++++++------
bin/chuankou/SerialPortConnectionDialog$1.class | 0
src/xitongshezhi/Charulog.java | 148 +
bin/xitongshezhi/ConfigSet$3.class | 0
bin/home/Homein.class | 0
bin/publicway/ProtocolParser01$DoorStatus.class | 0
/dev/null | 0
bin/xitongshezhi/banbenguanli.class | 0
src/chushihua/lunxun.java | 262 ++
src/publicway/SerialProtocolParser.java | 4
bin/chushihua/lunxun.class | 0
src/chuankou/SerialPortConnectionDialog.java | 3
52 files changed, 3,734 insertions(+), 1,164 deletions(-)
diff --git a/.classpath b/.classpath
index b6f4065..8404967 100644
--- a/.classpath
+++ b/.classpath
@@ -7,5 +7,7 @@
</classpathentry>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="lib/jSerialComm-2.10.4.jar"/>
+ <classpathentry kind="lib" path="lib/slf4j-api-1.7.30.jar"/>
+ <classpathentry kind="lib" path="lib/slf4j-simple-1.7.30.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
index 0d656b3..2a67676 100644
--- a/.settings/org.eclipse.core.resources.prefs
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -3,3 +3,4 @@
encoding//src/publicway/ProtocolParser01.java=GBK
encoding//src/publicway/ProtocolParser51.java=GBK
encoding//src/publicway/SerialProtocolParser.java=UTF-8
+encoding/log.properties=GBK
diff --git a/bin/chuankou/SerialPortConnectionDialog$1.class b/bin/chuankou/SerialPortConnectionDialog$1.class
index 3f90483..f3bc901 100644
--- a/bin/chuankou/SerialPortConnectionDialog$1.class
+++ b/bin/chuankou/SerialPortConnectionDialog$1.class
Binary files differ
diff --git a/bin/chuankou/SerialPortConnectionDialog.class b/bin/chuankou/SerialPortConnectionDialog.class
index 334a6be..ce51954 100644
--- a/bin/chuankou/SerialPortConnectionDialog.class
+++ b/bin/chuankou/SerialPortConnectionDialog.class
Binary files differ
diff --git a/bin/chuankou/SerialPortService.class b/bin/chuankou/SerialPortService.class
index 7b1329d..4efcaef 100644
--- a/bin/chuankou/SerialPortService.class
+++ b/bin/chuankou/SerialPortService.class
Binary files differ
diff --git a/bin/chuankou/SystemDebugDialog$1.class b/bin/chuankou/SystemDebugDialog$1.class
deleted file mode 100644
index aa2c95a..0000000
--- a/bin/chuankou/SystemDebugDialog$1.class
+++ /dev/null
Binary files differ
diff --git a/bin/chuankou/SystemDebugDialog.class b/bin/chuankou/SystemDebugDialog.class
deleted file mode 100644
index 3debd24..0000000
--- a/bin/chuankou/SystemDebugDialog.class
+++ /dev/null
Binary files differ
diff --git a/bin/chushihua/SlotManager.class b/bin/chushihua/SlotManager.class
index 7f78200..875045b 100644
--- a/bin/chushihua/SlotManager.class
+++ b/bin/chushihua/SlotManager.class
Binary files differ
diff --git a/bin/chushihua/lunxun$PollingTask.class b/bin/chushihua/lunxun$PollingTask.class
index 9a59a95..06d7b40 100644
--- a/bin/chushihua/lunxun$PollingTask.class
+++ b/bin/chushihua/lunxun$PollingTask.class
Binary files differ
diff --git a/bin/chushihua/lunxun.class b/bin/chushihua/lunxun.class
index b34f82c..c3b8532 100644
--- a/bin/chushihua/lunxun.class
+++ b/bin/chushihua/lunxun.class
Binary files differ
diff --git a/bin/home/CardMachineUI$1.class b/bin/home/CardMachineUI$1.class
index d8ffaf7..b974ee2 100644
--- a/bin/home/CardMachineUI$1.class
+++ b/bin/home/CardMachineUI$1.class
Binary files differ
diff --git a/bin/home/CardMachineUI$2.class b/bin/home/CardMachineUI$2.class
deleted file mode 100644
index 0f786f4..0000000
--- a/bin/home/CardMachineUI$2.class
+++ /dev/null
Binary files differ
diff --git a/bin/home/CardMachineUI.class b/bin/home/CardMachineUI.class
index b3ee2fe..88cfd63 100644
--- a/bin/home/CardMachineUI.class
+++ b/bin/home/CardMachineUI.class
Binary files differ
diff --git a/bin/home/Homein.class b/bin/home/Homein.class
index 801dd10..bc75bf9 100644
--- a/bin/home/Homein.class
+++ b/bin/home/Homein.class
Binary files differ
diff --git a/bin/publicway/ProtocolParser01$CardStatus.class b/bin/publicway/ProtocolParser01$CardStatus.class
index 4ae2b86..3e78a0b 100644
--- a/bin/publicway/ProtocolParser01$CardStatus.class
+++ b/bin/publicway/ProtocolParser01$CardStatus.class
Binary files differ
diff --git a/bin/publicway/ProtocolParser01$DoorStatus.class b/bin/publicway/ProtocolParser01$DoorStatus.class
index e30f065..8dddec2 100644
--- a/bin/publicway/ProtocolParser01$DoorStatus.class
+++ b/bin/publicway/ProtocolParser01$DoorStatus.class
Binary files differ
diff --git a/bin/publicway/ProtocolParser01$FaultType.class b/bin/publicway/ProtocolParser01$FaultType.class
index b165171..ea11a28 100644
--- a/bin/publicway/ProtocolParser01$FaultType.class
+++ b/bin/publicway/ProtocolParser01$FaultType.class
Binary files differ
diff --git a/bin/publicway/ProtocolParser01$ParseResult.class b/bin/publicway/ProtocolParser01$ParseResult.class
index 91d48ed..4f78fd2 100644
--- a/bin/publicway/ProtocolParser01$ParseResult.class
+++ b/bin/publicway/ProtocolParser01$ParseResult.class
Binary files differ
diff --git a/bin/publicway/ProtocolParser01$ParseResultPool.class b/bin/publicway/ProtocolParser01$ParseResultPool.class
index d04854e..5ab9cd1 100644
--- a/bin/publicway/ProtocolParser01$ParseResultPool.class
+++ b/bin/publicway/ProtocolParser01$ParseResultPool.class
Binary files differ
diff --git a/bin/publicway/ProtocolParser01$WorkStatus.class b/bin/publicway/ProtocolParser01$WorkStatus.class
index 433913d..66c075e 100644
--- a/bin/publicway/ProtocolParser01$WorkStatus.class
+++ b/bin/publicway/ProtocolParser01$WorkStatus.class
Binary files differ
diff --git a/bin/publicway/ProtocolParser01.class b/bin/publicway/ProtocolParser01.class
index 8e76c68..453e7e0 100644
--- a/bin/publicway/ProtocolParser01.class
+++ b/bin/publicway/ProtocolParser01.class
Binary files differ
diff --git a/bin/publicway/SerialProtocolParser.class b/bin/publicway/SerialProtocolParser.class
index fbad36f..c781bd5 100644
--- a/bin/publicway/SerialProtocolParser.class
+++ b/bin/publicway/SerialProtocolParser.class
Binary files differ
diff --git a/bin/xitongshezhi/ConfigSet$1.class b/bin/xitongshezhi/ConfigSet$1.class
index 2d19f25..8abaab9 100644
--- a/bin/xitongshezhi/ConfigSet$1.class
+++ b/bin/xitongshezhi/ConfigSet$1.class
Binary files differ
diff --git a/bin/xitongshezhi/ConfigSet$2.class b/bin/xitongshezhi/ConfigSet$2.class
index 6cdddfd..418e4b0 100644
--- a/bin/xitongshezhi/ConfigSet$2.class
+++ b/bin/xitongshezhi/ConfigSet$2.class
Binary files differ
diff --git a/bin/xitongshezhi/ConfigSet$3.class b/bin/xitongshezhi/ConfigSet$3.class
index 9d90489..4b554ed 100644
--- a/bin/xitongshezhi/ConfigSet$3.class
+++ b/bin/xitongshezhi/ConfigSet$3.class
Binary files differ
diff --git a/bin/xitongshezhi/ConfigSet$MenuItemListener.class b/bin/xitongshezhi/ConfigSet$MenuItemListener.class
index bc30ead..9334df6 100644
--- a/bin/xitongshezhi/ConfigSet$MenuItemListener.class
+++ b/bin/xitongshezhi/ConfigSet$MenuItemListener.class
Binary files differ
diff --git a/bin/xitongshezhi/ConfigSet.class b/bin/xitongshezhi/ConfigSet.class
index 2b255ff..429eba8 100644
--- a/bin/xitongshezhi/ConfigSet.class
+++ b/bin/xitongshezhi/ConfigSet.class
Binary files differ
diff --git a/bin/xitongshezhi/banbenguanli$1.class b/bin/xitongshezhi/banbenguanli$1.class
index 7227a69..59907fd 100644
--- a/bin/xitongshezhi/banbenguanli$1.class
+++ b/bin/xitongshezhi/banbenguanli$1.class
Binary files differ
diff --git a/bin/xitongshezhi/banbenguanli.class b/bin/xitongshezhi/banbenguanli.class
index e25561c..f89f224 100644
--- a/bin/xitongshezhi/banbenguanli.class
+++ b/bin/xitongshezhi/banbenguanli.class
Binary files differ
diff --git a/bin/xitongshezhi/lishijilu$1.class b/bin/xitongshezhi/lishijilu$1.class
index c3b6fac..ff88e6d 100644
--- a/bin/xitongshezhi/lishijilu$1.class
+++ b/bin/xitongshezhi/lishijilu$1.class
Binary files differ
diff --git a/bin/xitongshezhi/lishijilu$HistoryRecord.class b/bin/xitongshezhi/lishijilu$HistoryRecord.class
deleted file mode 100644
index 9cdde0d..0000000
--- a/bin/xitongshezhi/lishijilu$HistoryRecord.class
+++ /dev/null
Binary files differ
diff --git a/bin/xitongshezhi/lishijilu$HistoryTableCellRenderer.class b/bin/xitongshezhi/lishijilu$HistoryTableCellRenderer.class
deleted file mode 100644
index cc6af3f..0000000
--- a/bin/xitongshezhi/lishijilu$HistoryTableCellRenderer.class
+++ /dev/null
Binary files differ
diff --git a/bin/xitongshezhi/lishijilu.class b/bin/xitongshezhi/lishijilu.class
index 297e263..5775070 100644
--- a/bin/xitongshezhi/lishijilu.class
+++ b/bin/xitongshezhi/lishijilu.class
Binary files differ
diff --git a/log.properties b/log.properties
new file mode 100644
index 0000000..0a5ac47
--- /dev/null
+++ b/log.properties
@@ -0,0 +1 @@
+测试
\ No newline at end of file
diff --git a/src/chuankou/SerialPortConnectionDialog.java b/src/chuankou/SerialPortConnectionDialog.java
index 3411358..d84ef12 100644
--- a/src/chuankou/SerialPortConnectionDialog.java
+++ b/src/chuankou/SerialPortConnectionDialog.java
@@ -4,17 +4,16 @@
import java.awt.*;
import com.fazecast.jSerialComm.SerialPort;
import chushihua.Chushihua;
-import home.CardMachineUI;
/**
* 涓插彛杩炴帴瀵硅瘽妗�
* 杞欢鍚姩鏃舵樉绀猴紝鐢ㄤ簬閫夋嫨涓插彛鍜屾尝鐗圭巼骞惰繛鎺�
*/
+@SuppressWarnings("serial")
public class SerialPortConnectionDialog extends JDialog {
// 棰滆壊甯搁噺
private static final Color PRIMARY_COLOR = new Color(52, 152, 219);
- private static final Color PRIMARY_DARK_COLOR = new Color(41, 128, 185);
private static final Color SECONDARY_COLOR = new Color(46, 204, 113);
private static final Color DANGER_COLOR = new Color(231, 76, 60);
private static final Color DARK_COLOR = new Color(255, 69, 0); // 鏀逛负姗橀粍鑹�
diff --git a/src/chuankou/SerialPortService.java b/src/chuankou/SerialPortService.java
index ca0f2ff..5fe532c 100644
--- a/src/chuankou/SerialPortService.java
+++ b/src/chuankou/SerialPortService.java
@@ -6,6 +6,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import publicway.SerialProtocolParser; // 娣诲姞瀵煎叆
+import xitongshezhi.SystemDebugDialog;
public class SerialPortService {
@@ -33,7 +34,7 @@
* 褰撴潯鏁拌秴杩�1涓囨椂鑷姩浠�1寮�濮嬮噸鏂拌鏁�
* @return 鏁版嵁鏉℃暟瀛楃涓�
*/
- public String getReceivedDataCount() {
+ public static String getReceivedDataCount() {
receivedDataCount++;
if (receivedDataCount > 10000) {
receivedDataCount = 1;
diff --git a/src/chushihua/SlotManager.java b/src/chushihua/SlotManager.java
index 00fbd7c..19ce442 100644
--- a/src/chushihua/SlotManager.java
+++ b/src/chushihua/SlotManager.java
@@ -273,15 +273,19 @@
* 鏂板锛氭牴鎹覆鍙e崗璁В鏋愬櫒鐨勭姸鎬佹洿鏂版潵鏇存柊鍗℃Ы璇︾粏淇℃伅 - 浼樺寲鐗堟湰
*/
public static boolean gengxinshuxingzhi(
- int slotNumber, String cardNumber, String hascard, String workStatus,String voltage, String current,String falt ) {
+ int slotNumber, String cardNumber, String hascard, String workStatus,
+ String voltage, String current, String falt) {
-
- if (!isValidSlotNumber(slotNumber) || cardNumber.equals("0000")) {
+ if (!isValidSlotNumber(slotNumber)) {
return false;
}
-
Fkj slot = slotArray[slotNumber-1];
+
+ // 鑾峰彇鏇存柊鍓嶇殑鍗″彿鐢ㄤ簬姣旇緝
+ String oldCardNumber = slot.getCardNumber();
+
+ // 鏇存柊鍗℃Ы灞炴��
slot.setCardNumber(cardNumber);
slot.setHasCard(hascard);
slot.setWorkStatus(workStatus);
@@ -290,6 +294,10 @@
slot.setFault(falt);
// 鏇存柊鏃堕棿
slot.setUpdateTime(getCurrentTime());
+
+ // 妫�娴嬪崱鍙峰彉鍖栧苟寮瑰嚭鎻愮ず
+ checkCardInsertionAndShowDialog(slotNumber, oldCardNumber, cardNumber);
+
return true;
}
@@ -448,19 +456,19 @@
System.out.println("鐘舵�佺紦瀛樺ぇ灏�: " + statusTextCache.size());
System.out.println("鏁呴殰缂撳瓨澶у皬: " + faultTextCache.size());
}
-
+
/**
* 缁熻鍏呯數涓殑鍗℃Ы鏁伴噺
* @return 鍏呯數涓殑鍗℃Ы鏁伴噺瀛楃涓�
*/
public static String getChargingCount() {
- int count = 0;
- for (Fkj slot : slotArray) {
- if ("2".equals(slot.getWorkStatus())) {
- count++;
- }
- }
- return String.valueOf(count);
+ int count = 0;
+ for (Fkj slot : slotArray) {
+ if ("2".equals(slot.getWorkStatus())) {
+ count++;
+ }
+ }
+ return String.valueOf(count);
}
/**
@@ -468,13 +476,13 @@
* @return 宸插厖婊$殑鍗℃Ы鏁伴噺瀛楃涓�
*/
public static String getFullyChargedCount() {
- int count = 0;
- for (Fkj slot : slotArray) {
- if ("3".equals(slot.getWorkStatus())) {
- count++;
- }
- }
- return String.valueOf(count);
+ int count = 0;
+ for (Fkj slot : slotArray) {
+ if ("3".equals(slot.getWorkStatus())) {
+ count++;
+ }
+ }
+ return String.valueOf(count);
}
/**
@@ -482,13 +490,13 @@
* @return 鏁呴殰鐨勫崱妲芥暟閲忓瓧绗︿覆
*/
public static String getFaultCount() {
- int count = 0;
- for (Fkj slot : slotArray) {
- if ("4".equals(slot.getWorkStatus())) {
- count++;
- }
- }
- return String.valueOf(count);
+ int count = 0;
+ for (Fkj slot : slotArray) {
+ if ("4".equals(slot.getWorkStatus())) {
+ count++;
+ }
+ }
+ return String.valueOf(count);
}
/**
@@ -496,12 +504,31 @@
* @return 閫氫俊瓒呮椂鐨勫崱妲芥暟閲忓瓧绗︿覆
*/
public static String getCommTimeoutCount() {
- int count = 0;
- for (Fkj slot : slotArray) {
- if ("6".equals(slot.getWorkStatus())) {
- count++;
- }
- }
- return String.valueOf(count);
+ int count = 0;
+ for (Fkj slot : slotArray) {
+ if ("6".equals(slot.getWorkStatus())) {
+ count++;
+ }
+ }
+ return String.valueOf(count);
+ }
+
+ /**
+ * 鏂板锛氭娴嬪崱鍙峰彉鍖栧苟寮瑰嚭杩樺崱鎴愬姛鎻愮ず
+ */
+ private static void checkCardInsertionAndShowDialog(int slotNumber, String oldCardNumber, String newCardNumber) {
+ // 妫�鏌ュ崱鍙锋槸鍚︿粠"0000"鍙樹负闈�"0000"
+ if ("0000".equals(oldCardNumber) && !"0000".equals(newCardNumber)) {
+ // 鍦ㄤ簨浠跺垎鍙戠嚎绋嬩腑鏄剧ず瀵硅瘽妗�
+ javax.swing.SwingUtilities.invokeLater(() -> {
+ xitongshezhi.Dingshidialog.showTimedDialog(
+ null, // 鐖剁獥鍙o紝鍙互涓簄ull
+ 5, // 鏄剧ず3绉�
+ "杩樺崱鎴愬姛锛屾劅璋㈡偍鐨勪娇鐢�",
+ "" // 闊抽鏂囦欢锛屽彲浠ヤ负绌�
+ );
+ });
+ System.out.println("鍗℃Ы " + slotNumber + " 杩樺崱鎴愬姛锛屽崱鍙蜂粠 " + oldCardNumber + " 鍙樹负 " + newCardNumber);
+ }
}
}
\ No newline at end of file
diff --git a/src/chushihua/lunxun.java b/src/chushihua/lunxun.java
index ac7e82d..6ed53dd 100644
--- a/src/chushihua/lunxun.java
+++ b/src/chushihua/lunxun.java
@@ -3,15 +3,22 @@
import chuankou.Sendmsg;
import home.MachineConfig;
import publicway.QueryData;
+import xitongshezhi.Fkj;
+import xitongshezhi.SystemDebugDialog;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
- * 杞鏌ヨ绫�
+ * 杞鏌ヨ绫� - 浼樺寲鐗堟湰
* 鐢ㄤ簬瀹氭椂鍚戞墍鏈夊崱妲藉彂閫佹煡璇㈡寚浠�
* 鏀寔鏆傚仠鍜屾仮澶嶅姛鑳斤紝妫�鏌ヤ覆鍙h繛鎺ョ姸鎬�
*/
public class lunxun {
private static volatile boolean isRunning = false;
private static volatile boolean isPaused = false;
+ private static final AtomicBoolean shouldStop = new AtomicBoolean(false);
private static Thread pollingThread;
private static int pollingInterval = 100; // 榛樿杞闂撮殧
@@ -24,8 +31,14 @@
private static long lastSerialCheckTime = 0;
private static boolean serialConnected = false;
+ // 鎬ц兘浼樺寲锛氭煡璇㈡寚浠ょ紦瀛�
+ private static final Map<Integer, String> queryCommandCache = new ConcurrentHashMap<>();
+
+ // 璋冭瘯妯″紡鎺у埗
+ public static boolean DEBUG_ENABLED = false;
+
/**
- * 妫�鏌ヤ覆鍙h繛鎺ョ姸鎬�
+ * 妫�鏌ヤ覆鍙h繛鎺ョ姸鎬� - 浼樺寲鐗堟湰锛屾坊鍔犻噸璇曟満鍒�
* @return true-涓插彛宸茶繛鎺�, false-涓插彛鏈繛鎺�
*/
public static boolean checkSerialConnection() {
@@ -42,7 +55,9 @@
boolean result = Sendmsg.isPortOpen();
if (result) {
- System.out.println("涓插彛杩炴帴姝e父");
+ if (DEBUG_ENABLED) {
+ System.out.println("涓插彛杩炴帴姝e父");
+ }
serialConnected = true;
} else {
System.err.println("涓插彛杩炴帴澶辫触 - 涓插彛鏈墦寮�");
@@ -57,7 +72,25 @@
}
/**
- * 鍚姩杞鏌ヨ
+ * 甯﹂噸璇曠殑涓插彛杩炴帴妫�鏌�
+ */
+ private static boolean checkSerialConnectionWithRetry() {
+ for (int i = 0; i < 3; i++) {
+ if (checkSerialConnection()) {
+ return true;
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 鍚姩杞鏌ヨ - 浼樺寲鐗堟湰
* @return true-鍚姩鎴愬姛, false-鍚姩澶辫触
*/
public static boolean startPolling() {
@@ -67,7 +100,7 @@
}
// 鍚姩鍓嶄弗鏍兼鏌ヤ覆鍙h繛鎺�
- if (!checkSerialConnection()) {
+ if (!checkSerialConnectionWithRetry()) {
System.err.println("涓插彛鏈繛鎺ワ紝鏃犳硶鍚姩杞鏌ヨ");
return false;
}
@@ -77,23 +110,26 @@
isRunning = true;
isPaused = false;
+ shouldStop.set(false);
try {
pollingThread = new Thread(new PollingTask(), "CardSlot-Polling-Thread");
pollingThread.setDaemon(true);
- pollingThread.start();
-
- System.out.println("杞鏌ヨ宸插惎鍔紝闂撮殧: " + pollingInterval + "ms");
+ pollingThread.start();
+ if (DEBUG_ENABLED) {
+ System.out.println("杞鏌ヨ宸插惎鍔紝闂撮殧: " + pollingInterval + "ms");
+ }
return true;
} catch (Exception e) {
System.err.println("鍚姩杞鏌ヨ绾跨▼鏃跺彂鐢熷紓甯�: " + e.getMessage());
isRunning = false;
+ shouldStop.set(true);
return false;
}
}
/**
- * 鍋滄杞鏌ヨ
+ * 鍋滄杞鏌ヨ - 淇鐗堟湰
* @return true-鍋滄鎴愬姛, false-鍋滄澶辫触
*/
public static boolean stopPolling() {
@@ -102,19 +138,31 @@
return false;
}
+ shouldStop.set(true);
isRunning = false;
isPaused = false;
+
if (pollingThread != null) {
pollingThread.interrupt();
try {
- pollingThread.join(1000); // 绛夊緟绾跨▼缁撴潫锛屾渶澶�1绉�
+ pollingThread.join(3000); // 绛夊緟3绉�
+ // 妫�鏌ョ嚎绋嬫槸鍚﹁繕鍦ㄨ繍琛�
+ if (pollingThread.isAlive()) {
+ System.err.println("杞绾跨▼鏈湪3绉掑唴鍋滄锛屾爣璁颁负瀹堟姢绾跨▼骞跺拷鐣�");
+ // 涓嶅己鍒跺仠姝紝鑰屾槸纭繚瀹冩槸瀹堟姢绾跨▼
+ pollingThread.setDaemon(true);
+ }
} catch (InterruptedException e) {
System.err.println("鍋滄杞鏌ヨ鏃惰涓柇: " + e.getMessage());
Thread.currentThread().interrupt();
+ } catch (Exception e) {
+ System.err.println("鍋滄杞绾跨▼鏃跺彂鐢熷紓甯�: " + e.getMessage());
+ } finally {
+ pollingThread = null;
}
- pollingThread = null;
}
+ shouldStop.set(false);
System.out.println("杞鏌ヨ宸插仠姝�");
return true;
}
@@ -125,12 +173,16 @@
*/
public static boolean pausePolling() {
if (!isRunning) {
- System.out.println("杞鏌ヨ鏈湪杩愯锛屾棤娉曟殏鍋�");
+ if (DEBUG_ENABLED) {
+ System.out.println("杞鏌ヨ鏈湪杩愯锛屾棤娉曟殏鍋�");
+ }
return false;
}
if (isPaused) {
- System.out.println("杞鏌ヨ宸茬粡澶勪簬鏆傚仠鐘舵��");
+ if (DEBUG_ENABLED) {
+ System.out.println("杞鏌ヨ宸茬粡澶勪簬鏆傚仠鐘舵��");
+ }
return false;
}
@@ -155,7 +207,7 @@
}
// 鎭㈠鍓嶆鏌ヤ覆鍙h繛鎺�
- if (!checkSerialConnection()) {
+ if (!checkSerialConnectionWithRetry()) {
System.err.println("涓插彛鏈繛鎺ワ紝鏃犳硶鎭㈠杞鏌ヨ");
return false;
}
@@ -228,7 +280,7 @@
// 绛夊緟涓�灏忔鏃堕棿纭繚绾跨▼瀹屽叏鍋滄
try {
- Thread.sleep(100);
+ Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
@@ -256,22 +308,40 @@
}
/**
- * 杞浠诲姟鍐呴儴绫�
+ * 鑾峰彇缂撳瓨鐨勬煡璇㈡寚浠�
+ */
+ private static String getCachedQueryCommand(int slotNumber) {
+ return queryCommandCache.computeIfAbsent(slotNumber, QueryData::queryData);
+ }
+
+ /**
+ * 娓呯┖鏌ヨ鎸囦护缂撳瓨锛堝綋鏌ヨ閫昏緫鍙樺寲鏃惰皟鐢級
+ */
+ public static void clearQueryCache() {
+ queryCommandCache.clear();
+ System.out.println("鏌ヨ鎸囦护缂撳瓨宸叉竻绌�");
+ }
+
+ /**
+ * 杞浠诲姟鍐呴儴绫� - 浼樺寲鐗堟湰
* 浼樺寲鍐呭瓨浣跨敤锛氶伩鍏嶅湪寰幆涓垱寤烘柊瀵硅薄
+ * 娣诲姞鎵归噺澶勭悊鍜屾�ц兘鐩戞帶
*/
private static class PollingTask implements Runnable {
- private int currentSlot = MIN_SLOT;
+ private int currentIndex = 0; // 褰撳墠绱㈠紩锛岀敤浜庨亶鍘唖lotArray
+ private int consecutiveFailures = 0; // 杩炵画澶辫触娆℃暟
+ private static final int MAX_CONSECUTIVE_FAILURES = 5; // 鏈�澶ц繛缁け璐ユ鏁�
@Override
public void run() {
System.out.println("杞鏌ヨ绾跨▼寮�濮嬭繍琛�");
- while (isRunning && !Thread.currentThread().isInterrupted()) {
+ while (isRunning && !Thread.currentThread().isInterrupted() && !shouldStop.get()) {
try {
// 妫�鏌ユ槸鍚︽殏鍋�
if (isPaused) {
synchronized (lunxun.class) {
- while (isPaused && isRunning) {
+ while (isPaused && isRunning && !shouldStop.get()) {
lunxun.class.wait(1000); // 绛夊緟1绉掓垨鐩村埌琚敜閱�
}
}
@@ -279,28 +349,61 @@
}
// 瀹氭湡妫�鏌ヤ覆鍙h繛鎺ョ姸鎬侊紙姣�10娆″惊鐜鏌ヤ竴娆★級
- if (currentSlot % 10 == 0 && !checkSerialConnection()) {
+ if (currentIndex % 10 == 0 && !checkSerialConnectionWithRetry()) {
System.err.println("涓插彛杩炴帴鏂紑锛屾殏鍋滆疆璇�");
pausePolling();
continue;
}
- // 鍙戦�佸綋鍓嶅崱妲界殑鏌ヨ鎸囦护
- sendQueryToSlot(currentSlot);
-
- // 绉诲姩鍒颁笅涓�涓崱妲�
- currentSlot++;
- if (currentSlot > MAX_SLOT) {
- currentSlot = MIN_SLOT; // 寰幆鍥炲埌绗竴涓崱妲�
-
- // 鍦ㄥ惊鐜洖鍒扮涓�涓崱妲藉悗锛岀瓑寰呴棿闅旀椂闂�
- // 閬垮厤杩炵画鍙戦�佷袱涓浉閭诲懆鏈熺殑绗竴涓崱妲�
+ // 鑾峰彇鍗℃Ы鏁扮粍
+ Fkj[] slotArray = SlotManager.getSlotArray();
+ if (slotArray == null || slotArray.length == 0) {
+ System.err.println("鍗℃Ы鏁扮粍鏈垵濮嬪寲");
Thread.sleep(pollingInterval);
- continue; // 璺宠繃鏈寰幆鐨勫悗缁瓑寰�
+ continue;
}
- // 绛夊緟鎸囧畾鐨勯棿闅旀椂闂�
- Thread.sleep(pollingInterval);
+ // 閬嶅巻鎵�鏈夊崱妲斤紝鍙粰 hasCard != 1 鐨勫崱妲藉彂閫佹煡璇㈡寚浠�
+ boolean sentQuery = false;
+ int checkedSlots = 0;
+ int maxSlotsPerCycle = Math.min(10, slotArray.length); // 姣忓懆鏈熸渶澶氭鏌�10涓崱妲�
+
+ for (int i = 0; i < maxSlotsPerCycle && checkedSlots < slotArray.length; i++) {
+ Fkj slot = slotArray[currentIndex];
+ if (slot != null) {
+ String hasCard = slot.getHasCard();
+ if (!"1".equals(hasCard)) {
+ int slotNumber = currentIndex + 1;
+ if (sendQueryToSlot(slotNumber)) {
+ sentQuery = true;
+ consecutiveFailures = 0;
+
+ // 鍏抽敭淇锛氬湪break鍓嶅厛鏇存柊绱㈠紩
+ currentIndex = (currentIndex + 1) % slotArray.length;
+ checkedSlots++;
+
+ Thread.sleep(pollingInterval);
+ break;
+ } else {
+ consecutiveFailures++;
+ if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
+ System.err.println("杩炵画澶辫触娆℃暟杩囧锛屾殏鍋滆疆璇�");
+ pausePolling();
+ break;
+ }
+ }
+ }
+ }
+
+ // 瀵逛簬涓嶉渶瑕佸彂閫佹煡璇㈢殑鍗℃Ы锛屾甯告洿鏂扮储寮�
+ currentIndex = (currentIndex + 1) % slotArray.length;
+ checkedSlots++;
+ }
+
+ // 濡傛灉娌℃湁鎵惧埌闇�瑕佹煡璇㈢殑鍗℃Ы锛岀瓑寰呬竴娈垫椂闂村啀缁х画
+ if (!sentQuery) {
+ Thread.sleep(pollingInterval * 2); // 娌℃湁鏌ヨ鏃剁瓑寰呮椂闂村姞鍊�
+ }
} catch (InterruptedException e) {
System.out.println("杞鏌ヨ绾跨▼琚腑鏂�");
@@ -308,6 +411,7 @@
break;
} catch (Exception e) {
System.err.println("杞鏌ヨ杩囩▼涓彂鐢熷紓甯�: " + e.getMessage());
+ consecutiveFailures++;
// 鍙戠敓寮傚父鏃剁瓑寰呬竴娈垫椂闂村啀缁х画
try {
@@ -323,13 +427,13 @@
}
/**
- * 鍚戞寚瀹氬崱妲藉彂閫佹煡璇㈡寚浠�
- * 浼樺寲锛氶伩鍏嶉噸澶嶅垱寤哄璞★紝浣跨敤灞�閮ㄥ彉閲�
+ * 鍚戞寚瀹氬崱妲藉彂閫佹煡璇㈡寚浠� - 浼樺寲鐗堟湰
+ * 浣跨敤缂撳瓨鎸囦护锛屼紭鍖栬皟璇曡緭鍑�
*/
- private void sendQueryToSlot(int slotNumber) {
+ private boolean sendQueryToSlot(int slotNumber) {
try {
- // 鐢熸垚鏌ヨ鎸囦护
- String queryCommand = QueryData.queryData(slotNumber);
+ // 浣跨敤缂撳瓨鐨勬煡璇㈡寚浠�
+ String queryCommand = getCachedQueryCommand(slotNumber);
if (queryCommand != null && !queryCommand.trim().isEmpty()) {
// 鍙戦�佸埌涓插彛
@@ -337,22 +441,28 @@
if (sendResult) {
// 鍙湪璋冭瘯鏃惰緭鍑猴紝閬垮厤棰戠箒鎵撳嵃
- if (slotNumber == 1 || slotNumber % 20 == 0) {
- System.out.println("鍙戦�佹煡璇㈡寚浠ゅ埌鍗℃Ы " + slotNumber);
+ if (DEBUG_ENABLED) {
+ SystemDebugDialog.appendAsciiData(String.format("Slot %d Send query (hasCard !=1)", slotNumber));
}
+ return true;
} else {
- System.err.println("鍙戦�佹煡璇㈡寚浠ゅ埌鍗℃Ы " + slotNumber + " 澶辫触");
+ if (DEBUG_ENABLED) {
+ SystemDebugDialog.appendAsciiData("Send query command to card slot err");
+ }
// 鍙戦�佸け璐ュ彲鑳芥槸涓插彛鏂紑锛屾洿鏂拌繛鎺ョ姸鎬�
serialConnected = false;
+ return false;
}
} else {
System.err.println("鐢熸垚鐨勬煡璇㈡寚浠や负绌猴紝鍗℃Ы: " + slotNumber);
+ return false;
}
} catch (Exception e) {
System.err.println("鍙戦�佹煡璇㈡寚浠ゅ埌鍗℃Ы " + slotNumber + " 鏃跺彂鐢熷紓甯�: " + e.getMessage());
// 鍙戠敓寮傚父鏃舵洿鏂颁覆鍙h繛鎺ョ姸鎬�
serialConnected = false;
+ return false;
}
}
}
@@ -369,21 +479,23 @@
}
// 妫�鏌ヤ覆鍙h繛鎺�
- if (!checkSerialConnection()) {
+ if (!checkSerialConnectionWithRetry()) {
System.err.println("涓插彛鏈繛鎺ワ紝鏃犳硶鍙戦�佹煡璇㈡寚浠�");
return false;
}
try {
- // 鐢熸垚鏌ヨ鎸囦护
- String queryCommand = QueryData.queryData(slotNumber);
+ // 浣跨敤缂撳瓨鐨勬煡璇㈡寚浠�
+ String queryCommand = getCachedQueryCommand(slotNumber);
if (queryCommand != null && !queryCommand.trim().isEmpty()) {
// 鍙戦�佸埌涓插彛
boolean sendResult = Sendmsg.sendMessage(queryCommand);
if (sendResult) {
- System.out.println("绔嬪嵆鏌ヨ鎴愬姛 - 鍗℃Ы " + slotNumber);
+ if (DEBUG_ENABLED) {
+ System.out.println("绔嬪嵆鏌ヨ鎴愬姛 - 鍗℃Ы " + slotNumber);
+ }
return true;
} else {
System.err.println("绔嬪嵆鏌ヨ澶辫触 - 鍙戦�佹寚浠ゅ埌鍗℃Ы " + slotNumber + " 澶辫触");
@@ -401,35 +513,48 @@
}
/**
- * 绔嬪嵆鍚戞墍鏈夊崱妲藉彂閫佹煡璇㈡寚浠わ紙鎵归噺锛�
+ * 绔嬪嵆鍚戞墍鏈夊崱妲藉彂閫佹煡璇㈡寚浠わ紙鎵归噺锛�- 浼樺寲鐗堟湰
* @return 鎴愬姛鍙戦�佺殑鎸囦护鏁伴噺
*/
public static int sendImmediateQueryToAll() {
// 妫�鏌ヤ覆鍙h繛鎺�
- if (!checkSerialConnection()) {
+ if (!checkSerialConnectionWithRetry()) {
System.err.println("涓插彛鏈繛鎺ワ紝鏃犳硶鍙戦�佹壒閲忔煡璇㈡寚浠�");
return 0;
}
int successCount = 0;
+ int batchSize = 5; // 姣忔壒娆″彂閫�5涓煡璇�
+ int totalSlots = MAX_SLOT - MIN_SLOT + 1;
System.out.println("寮�濮嬫壒閲忔煡璇㈡墍鏈夊崱妲�...");
- for (int slot = MIN_SLOT; slot <= MAX_SLOT; slot++) {
- if (sendImmediateQuery(slot)) {
- successCount++;
+ for (int batchStart = MIN_SLOT; batchStart <= MAX_SLOT; batchStart += batchSize) {
+ if (shouldStop.get()) {
+ break;
}
- // 灏忛棿闅旈伩鍏嶄覆鍙f嫢鍫�
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- break;
+ int batchEnd = Math.min(batchStart + batchSize - 1, MAX_SLOT);
+
+ // 鎵规鍐呮煡璇�
+ for (int slot = batchStart; slot <= batchEnd; slot++) {
+ if (sendImmediateQuery(slot)) {
+ successCount++;
+ }
+ }
+
+ // 鎵规闂撮棿闅旓紝閬垮厤涓插彛鎷ュ牭
+ if (batchEnd < MAX_SLOT) {
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ break;
+ }
}
}
- System.out.println("鎵归噺鏌ヨ瀹屾垚锛屾垚鍔熷彂閫�: " + successCount + "/" + MAX_SLOT);
+ System.out.println("鎵归噺鏌ヨ瀹屾垚锛屾垚鍔熷彂閫�: " + successCount + "/" + totalSlots);
return successCount;
}
@@ -467,9 +592,10 @@
}
String serialStatus = serialConnected ? "宸茶繛鎺�" : "鏈繛鎺�";
+ int cacheSize = queryCommandCache.size();
- return String.format("杞鐘舵��: %s, 涓插彛: %s, 闂撮殧: %dms, 鍗℃Ы鑼冨洿: %d-%d",
- status, serialStatus, pollingInterval, MIN_SLOT, MAX_SLOT);
+ return String.format("杞鐘舵��: %s, 涓插彛: %s, 闂撮殧: %dms, 鎸囦护缂撳瓨: %d, 鍗℃Ы鑼冨洿: %d-%d",
+ status, serialStatus, pollingInterval, cacheSize, MIN_SLOT, MAX_SLOT);
}
/**
@@ -497,7 +623,7 @@
// 璇锋眰鎭㈠
if (isPaused) {
// 鎭㈠鍓嶆鏌ヤ覆鍙h繛鎺�
- if (!checkSerialConnection()) {
+ if (!checkSerialConnectionWithRetry()) {
System.err.println("涓插彛鏈繛鎺ワ紝鏃犳硶鎭㈠杞鏌ヨ");
return false;
}
@@ -514,4 +640,20 @@
}
}
}
+
+ /**
+ * 鑾峰彇鎬ц兘缁熻淇℃伅
+ */
+ public static String getPerformanceStats() {
+ return String.format("鏌ヨ鎸囦护缂撳瓨澶у皬: %d, 杞闂撮殧: %dms",
+ queryCommandCache.size(), pollingInterval);
+ }
+
+ public static boolean isDEBUG_ENABLED() {
+ return DEBUG_ENABLED;
+ }
+
+ public static void setDEBUG_ENABLED(boolean dEBUG_ENABLED) {
+ DEBUG_ENABLED = dEBUG_ENABLED;
+ }
}
\ No newline at end of file
diff --git a/src/chushihua/lunxunzaixian.java b/src/chushihua/lunxunzaixian.java
new file mode 100644
index 0000000..f4eeffa
--- /dev/null
+++ b/src/chushihua/lunxunzaixian.java
@@ -0,0 +1,492 @@
+package chushihua;
+
+import xitongshezhi.Fkj;
+import xitongshezhi.SystemDebugDialog;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * 鍦ㄧ嚎杞绫� - 浼樺寲鐗堟湰
+ * 涓撻棬鐢ㄤ簬瀹氭椂杞鏈夊崱鐨勫崱妲藉苟鍙戦�佹煡璇㈡寚浠�
+ * 涓庡師鏈夌殑杞鏌ヨ绫讳簰琛ワ紝涓撴敞浜庡湪绾胯澶囩殑鎸佺画鐩戞帶
+ */
+public class lunxunzaixian {
+ private static final AtomicBoolean isRunning = new AtomicBoolean(false);
+ private static final AtomicBoolean isPaused = new AtomicBoolean(false);
+ private static final AtomicBoolean shouldStop = new AtomicBoolean(false);
+ private static Thread onlinePollingThread;
+
+ // 鍙厤缃殑杞鍙傛暟锛堜笉鍐嶆槸final锛�
+ private static int cycleInterval = 60000; // 瀹屾暣杞鍛ㄦ湡闂撮殧锛�60绉�
+ private static int slotInterval = 200; // 鍗℃Ы闂存煡璇㈤棿闅旓細200姣
+
+ // 鍗℃Ы鐩稿叧甯搁噺
+ private static final int MIN_SLOT = 1;
+ private static final int MAX_SLOT = 60;
+
+ // 鎬ц兘浼樺寲閰嶇疆
+ private static final int BATCH_SIZE = 5; // 鎵归噺鏌ヨ澶у皬
+ private static int consecutiveFailures = 0;
+ private static final int MAX_CONSECUTIVE_FAILURES = 3;
+
+ /**
+ * 鍚姩鍦ㄧ嚎杞 - 浼樺寲鐗堟湰
+ * @return true-鍚姩鎴愬姛, false-鍚姩澶辫触
+ */
+ public static boolean startOnlinePolling() {
+ if (isRunning.get()) {
+ SystemDebugDialog.appendAsciiData("Online polling is already in progress");
+ return true;
+ }
+
+ // 妫�鏌ヤ覆鍙h繛鎺ョ姸鎬�
+ if (!checkSerialConnectionWithRetry()) {
+ System.err.println("涓插彛鏈繛鎺ワ紝鏃犳硶鍚姩鍦ㄧ嚎杞");
+ return false;
+ }
+
+ isRunning.set(true);
+ isPaused.set(false);
+ shouldStop.set(false);
+ consecutiveFailures = 0;
+
+ try {
+ onlinePollingThread = new Thread(new OnlinePollingTask(), "Online-Polling-Thread");
+ onlinePollingThread.setDaemon(true);
+ onlinePollingThread.start();
+ System.out.println("鍦ㄧ嚎杞宸插惎鍔紝鍛ㄦ湡闂撮殧: " + cycleInterval + "ms, 鍗℃Ы闂撮殧: " + slotInterval + "ms");
+ return true;
+ } catch (Exception e) {
+ System.err.println("鍚姩鍦ㄧ嚎杞绾跨▼鏃跺彂鐢熷紓甯�: " + e.getMessage());
+ isRunning.set(false);
+ shouldStop.set(true);
+ return false;
+ }
+ }
+
+ /**
+ * 鍋滄鍦ㄧ嚎杞 - 淇鐗堟湰
+ * @return true-鍋滄鎴愬姛, false-鍋滄澶辫触
+ */
+ public static boolean stopOnlinePolling() {
+ if (!isRunning.get()) {
+ System.out.println("鍦ㄧ嚎杞鏈湪杩愯");
+ return false;
+ }
+
+ shouldStop.set(true);
+ isRunning.set(false);
+ isPaused.set(false);
+
+ if (onlinePollingThread != null) {
+ onlinePollingThread.interrupt();
+ try {
+ onlinePollingThread.join(3000); // 绛夊緟3绉�
+ // 妫�鏌ョ嚎绋嬫槸鍚﹁繕鍦ㄨ繍琛�
+ if (onlinePollingThread.isAlive()) {
+ System.err.println("鍦ㄧ嚎杞绾跨▼鏈湪3绉掑唴鍋滄锛屾爣璁颁负瀹堟姢绾跨▼骞跺拷鐣�");
+ // 涓嶅己鍒跺仠姝紝鑰屾槸纭繚瀹冩槸瀹堟姢绾跨▼
+ onlinePollingThread.setDaemon(true);
+ }
+ } catch (InterruptedException e) {
+ System.err.println("鍋滄鍦ㄧ嚎杞鏃惰涓柇: " + e.getMessage());
+ Thread.currentThread().interrupt();
+ } catch (Exception e) {
+ System.err.println("鍋滄鍦ㄧ嚎杞绾跨▼鏃跺彂鐢熷紓甯�: " + e.getMessage());
+ } finally {
+ onlinePollingThread = null;
+ }
+ }
+
+ shouldStop.set(false);
+ System.out.println("鍦ㄧ嚎杞宸插仠姝�");
+ return true;
+ }
+
+ /**
+ * 鏆傚仠鍦ㄧ嚎杞
+ * @return true-鏆傚仠鎴愬姛, false-鏆傚仠澶辫触
+ */
+ public static boolean pauseOnlinePolling() {
+ if (!isRunning.get()) {
+ System.out.println("鍦ㄧ嚎杞鏈湪杩愯锛屾棤娉曟殏鍋�");
+ return false;
+ }
+
+ if (isPaused.get()) {
+ System.out.println("鍦ㄧ嚎杞宸茬粡澶勪簬鏆傚仠鐘舵��");
+ return false;
+ }
+
+ isPaused.set(true);
+ System.out.println("鍦ㄧ嚎杞宸叉殏鍋�");
+ return true;
+ }
+
+ /**
+ * 鎭㈠鍦ㄧ嚎杞
+ * @return true-鎭㈠鎴愬姛, false-鎭㈠澶辫触
+ */
+ public static boolean resumeOnlinePolling() {
+ if (!isRunning.get()) {
+ System.out.println("鍦ㄧ嚎杞鏈湪杩愯锛屾棤娉曟仮澶�");
+ return false;
+ }
+
+ if (!isPaused.get()) {
+ System.out.println("鍦ㄧ嚎杞鏈浜庢殏鍋滅姸鎬�");
+ return false;
+ }
+
+ // 鎭㈠鍓嶆鏌ヤ覆鍙h繛鎺�
+ if (!checkSerialConnectionWithRetry()) {
+ System.err.println("涓插彛鏈繛鎺ワ紝鏃犳硶鎭㈠鍦ㄧ嚎杞");
+ return false;
+ }
+
+ isPaused.set(false);
+ synchronized (lunxunzaixian.class) {
+ lunxunzaixian.class.notifyAll(); // 鍞ら啋绛夊緟鐨勭嚎绋�
+ }
+ System.out.println("鍦ㄧ嚎杞宸叉仮澶�");
+ return true;
+ }
+
+ /**
+ * 妫�鏌ュ湪绾胯疆璇㈢姸鎬�
+ * @return true-姝e湪杩愯, false-宸插仠姝�
+ */
+ public static boolean isOnlinePolling() {
+ return isRunning.get();
+ }
+
+ /**
+ * 妫�鏌ユ槸鍚︽殏鍋�
+ * @return true-宸叉殏鍋�, false-鏈殏鍋�
+ */
+ public static boolean isOnlinePaused() {
+ return isPaused.get();
+ }
+
+ /**
+ * 閲嶆柊鍚姩鍦ㄧ嚎杞
+ * @return true-閲嶅惎鎴愬姛, false-閲嶅惎澶辫触
+ */
+ public static boolean restartOnlinePolling() {
+ stopOnlinePolling();
+
+ // 绛夊緟涓�灏忔鏃堕棿纭繚绾跨▼瀹屽叏鍋滄
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+
+ return startOnlinePolling();
+ }
+
+ /**
+ * 璁剧疆杞闂撮殧鍙傛暟
+ * @param cycleMs 瀹屾暣杞鍛ㄦ湡闂撮殧锛堟绉掞級
+ * @param slotMs 鍗℃Ы闂存煡璇㈤棿闅旓紙姣锛�
+ */
+ public static void setPollingIntervals(int cycleMs, int slotMs) {
+ cycleInterval = Math.max(cycleMs, 1000); // 鏈�灏�1绉�
+ slotInterval = Math.max(slotMs, 50); // 鏈�灏�50姣
+ System.out.println("鍦ㄧ嚎杞闂撮殧宸茶缃� - 鍛ㄦ湡闂撮殧: " + cycleInterval + "ms, 鍗℃Ы闂撮殧: " + slotInterval + "ms");
+
+ // 濡傛灉姝e湪杩愯锛岄噸鏂板惎鍔ㄤ互搴旂敤鏂扮殑闂撮殧
+ if (isRunning.get()) {
+ restartOnlinePolling();
+ }
+ }
+
+ /**
+ * 鑾峰彇褰撳墠杞闂撮殧閰嶇疆
+ * @return 闂撮殧閰嶇疆瀛楃涓�
+ */
+ public static String getPollingIntervals() {
+ return String.format("鍛ㄦ湡闂撮殧: %dms, 鍗℃Ы闂撮殧: %dms", cycleInterval, slotInterval);
+ }
+
+ /**
+ * 鑾峰彇鍦ㄧ嚎杞缁熻淇℃伅
+ * @return 缁熻淇℃伅瀛楃涓�
+ */
+ public static String getOnlinePollingStats() {
+ int totalSlots = MAX_SLOT - MIN_SLOT + 1;
+ int cardSlots = countCardSlots();
+
+ String status;
+ if (!isRunning.get()) {
+ status = "宸插仠姝�";
+ } else if (isPaused.get()) {
+ status = "宸叉殏鍋�";
+ } else {
+ status = "杩愯涓�";
+ }
+
+ return String.format("鍦ㄧ嚎杞鐘舵��: %s, 鏈夊崱鍗℃Ы: %d/%d, 鍛ㄦ湡闂撮殧: %ds, 鍗℃Ы闂撮殧: %dms",
+ status, cardSlots, totalSlots, cycleInterval/1000, slotInterval);
+ }
+
+ /**
+ * 缁熻鏈夊崱鐨勫崱妲芥暟閲�
+ * @return 鏈夊崱鐨勫崱妲芥暟閲�
+ */
+ private static int countCardSlots() {
+ if (SlotManager.slotArray == null) {
+ return 0;
+ }
+
+ int count = 0;
+ for (Fkj slot : SlotManager.slotArray) {
+ if (slot != null && "1".equals(slot.getHasCard())) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ /**
+ * 甯﹂噸璇曠殑涓插彛杩炴帴妫�鏌�
+ */
+ private static boolean checkSerialConnectionWithRetry() {
+ for (int i = 0; i < 3; i++) {
+ if (lunxun.checkSerialConnection()) {
+ return true;
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 鍦ㄧ嚎杞浠诲姟鍐呴儴绫� - 浼樺寲鐗堟湰
+ * 涓撻棬杞鏈夊崱鐨勫崱妲斤紝浼樺寲璧勬簮浣跨敤
+ */
+ private static class OnlinePollingTask implements Runnable {
+ @Override
+ public void run() {
+ System.out.println("鍦ㄧ嚎杞绾跨▼寮�濮嬭繍琛�");
+
+ while (isRunning.get() && !Thread.currentThread().isInterrupted() && !shouldStop.get()) {
+ try {
+ // 妫�鏌ユ槸鍚︽殏鍋�
+ if (isPaused.get()) {
+ synchronized (lunxunzaixian.class) {
+ while (isPaused.get() && isRunning.get() && !shouldStop.get()) {
+ lunxunzaixian.class.wait(1000); // 绛夊緟1绉掓垨鐩村埌琚敜閱�
+ }
+ }
+ continue;
+ }
+
+ // 妫�鏌ヤ覆鍙h繛鎺ョ姸鎬�
+ if (!checkSerialConnectionWithRetry()) {
+ System.err.println("涓插彛杩炴帴鏂紑锛屾殏鍋滃湪绾胯疆璇�");
+ pauseOnlinePolling();
+ continue;
+ }
+
+ // 鎵ц涓�杞湁鍗″崱妲界殑杞
+ if (pollCardSlotsOptimized()) {
+ consecutiveFailures = 0; // 閲嶇疆杩炵画澶辫触璁℃暟
+ } else {
+ consecutiveFailures++;
+ if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
+ System.err.println("杩炵画澶辫触娆℃暟杩囧锛屾殏鍋滃湪绾胯疆璇�");
+ pauseOnlinePolling();
+ }
+ }
+
+ // 绛夊緟瀹屾暣鍛ㄦ湡闂撮殧
+ Thread.sleep(cycleInterval);
+
+ } catch (InterruptedException e) {
+ System.out.println("鍦ㄧ嚎杞绾跨▼琚腑鏂�");
+ Thread.currentThread().interrupt();
+ break;
+ } catch (Exception e) {
+ System.err.println("鍦ㄧ嚎杞杩囩▼涓彂鐢熷紓甯�: " + e.getMessage());
+ consecutiveFailures++;
+
+ // 鍙戠敓寮傚父鏃剁瓑寰呬竴娈垫椂闂村啀缁х画
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ break;
+ }
+ }
+ }
+
+ System.out.println("鍦ㄧ嚎杞绾跨▼缁撴潫杩愯");
+ }
+
+ /**
+ * 浼樺寲鐗堟湰锛氭壒閲忚疆璇㈡湁鍗″崱妲�
+ * @return true-杞鎴愬姛, false-杞澶辫触
+ */
+ private boolean pollCardSlotsOptimized() {
+ if (SlotManager.slotArray == null) {
+ System.err.println("鍗℃Ы鏁扮粍鏈垵濮嬪寲");
+ return false;
+ }
+
+ List<Integer> cardSlots = new ArrayList<>();
+
+ // 绗竴闃舵锛氭敹闆嗘墍鏈夋湁鍗″崱妲�
+ for (int i = 0; i < SlotManager.slotArray.length; i++) {
+ if (!isRunning.get() || Thread.currentThread().isInterrupted() || shouldStop.get()) {
+ break;
+ }
+
+ Fkj slot = SlotManager.slotArray[i];
+ if (slot != null && "1".equals(slot.getHasCard())) {
+ cardSlots.add(i + 1);
+ }
+ }
+
+ if (cardSlots.isEmpty()) {
+ if (lunxun.DEBUG_ENABLED) {
+ System.out.println("娌℃湁鎵惧埌鏈夊崱鐨勫崱妲�");
+ }
+ return true;
+ }
+
+ int polledCount = 0;
+ int totalCardSlots = cardSlots.size();
+
+ // 绗簩闃舵锛氭壒閲忔煡璇㈡湁鍗″崱妲�
+ for (int i = 0; i < cardSlots.size(); i += BATCH_SIZE) {
+ if (!isRunning.get() || Thread.currentThread().isInterrupted() || shouldStop.get()) {
+ break;
+ }
+
+ int end = Math.min(i + BATCH_SIZE, cardSlots.size());
+ List<Integer> batch = cardSlots.subList(i, end);
+
+ // 鎵规鍐呮煡璇�
+ for (int slotNumber : batch) {
+ if (sendQueryToCardSlot(slotNumber)) {
+ polledCount++;
+ }
+ }
+
+ // 鎵规闂撮棿闅�
+ if (end < cardSlots.size()) {
+ try {
+ Thread.sleep(slotInterval * BATCH_SIZE);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ break;
+ }
+ }
+ }
+
+ if (polledCount > 0 && lunxun.DEBUG_ENABLED) {
+ System.out.println("鍦ㄧ嚎杞瀹屾垚锛屾垚鍔熸煡璇� " + polledCount + "/" + totalCardSlots + " 涓湁鍗″崱妲�");
+ }
+
+ return polledCount > 0;
+ }
+
+ /**
+ * 鍚戞寚瀹氭湁鍗″崱妲藉彂閫佹煡璇㈡寚浠�
+ * @param slotNumber 鍗℃Ы缂栧彿
+ * @return true-鍙戦�佹垚鍔�, false-鍙戦�佸け璐�
+ */
+ private boolean sendQueryToCardSlot(int slotNumber) {
+ try {
+ // 浣跨敤鍘熸湁鐨勭珛鍗虫煡璇㈠姛鑳�
+ boolean result = lunxun.sendImmediateQuery(slotNumber);
+
+ if (result) {
+ // 璁板綍璋冭瘯淇℃伅锛堝噺灏戣緭鍑洪鐜囷級
+ if (lunxun.DEBUG_ENABLED && (slotNumber == 1 || slotNumber % 10 == 0)) {
+ System.out.println("鍦ㄧ嚎杞 - 鏌ヨ鏈夊崱鍗℃Ы " + slotNumber);
+ }
+ return true;
+ } else {
+ System.err.println("鍦ㄧ嚎杞 - 鏌ヨ鏈夊崱鍗℃Ы " + slotNumber + " 澶辫触");
+ return false;
+ }
+
+ } catch (Exception e) {
+ System.err.println("鍦ㄧ嚎杞 - 鏌ヨ鏈夊崱鍗℃Ы " + slotNumber + " 鏃跺彂鐢熷紓甯�: " + e.getMessage());
+ return false;
+ }
+ }
+ }
+
+ /**
+ * 鎵嬪姩瑙﹀彂绔嬪嵆杞锛堜笉绛夊緟鍛ㄦ湡锛�- 浼樺寲鐗堟湰
+ * @return 鎴愬姛鏌ヨ鐨勫崱妲芥暟閲�
+ */
+ public static int triggerImmediatePolling() {
+ if (!isRunning.get() || isPaused.get()) {
+ System.err.println("鍦ㄧ嚎杞鏈繍琛屾垨宸叉殏鍋滐紝鏃犳硶绔嬪嵆杞");
+ return 0;
+ }
+
+ if (!checkSerialConnectionWithRetry()) {
+ System.err.println("涓插彛鏈繛鎺ワ紝鏃犳硶鎵ц绔嬪嵆杞");
+ return 0;
+ }
+
+ System.out.println("寮�濮嬬珛鍗宠疆璇㈡湁鍗″崱妲�...");
+
+ OnlinePollingTask task = new OnlinePollingTask();
+
+ // 浣跨敤鏂扮殑鎵归噺杞鏂规硶
+ int cardSlotCount = countCardSlots();
+
+ // 鍦ㄦ柊绾跨▼涓墽琛岀珛鍗宠疆璇紝閬垮厤闃诲褰撳墠绾跨▼
+ Thread immediateThread = new Thread(() -> {
+ try {
+ task.pollCardSlotsOptimized();
+ } catch (Exception e) {
+ System.err.println("绔嬪嵆杞杩囩▼涓彂鐢熷紓甯�: " + e.getMessage());
+ }
+ }, "Immediate-Online-Polling");
+
+ immediateThread.setDaemon(true);
+ immediateThread.start();
+
+ return cardSlotCount;
+ }
+
+ /**
+ * 璁剧疆鍦ㄧ嚎杞鏆傚仠鐘舵�侊紙渚涘叾浠栫被璋冪敤锛�
+ * @param paused true-鏆傚仠杞, false-鎭㈠杞
+ * @return true-璁剧疆鎴愬姛, false-璁剧疆澶辫触
+ */
+ public static boolean setOnlinePollingPaused(boolean paused) {
+ if (!isRunning.get()) {
+ System.out.println("鍦ㄧ嚎杞鏈湪杩愯锛屾棤娉曡缃殏鍋滅姸鎬�");
+ return false;
+ }
+
+ if (paused) {
+ return pauseOnlinePolling();
+ } else {
+ return resumeOnlinePolling();
+ }
+ }
+
+ /**
+ * 鑾峰彇鎬ц兘缁熻淇℃伅
+ */
+ public static String getPerformanceStats() {
+ return String.format("鎵归噺澶у皬: %d, 鍛ㄦ湡闂撮殧: %dms, 鍗℃Ы闂撮殧: %dms",
+ BATCH_SIZE, cycleInterval, slotInterval);
+ }
+}
\ No newline at end of file
diff --git a/src/home/CardMachineUI.java b/src/home/CardMachineUI.java
index 12e7f49..291cd45 100644
--- a/src/home/CardMachineUI.java
+++ b/src/home/CardMachineUI.java
@@ -466,9 +466,6 @@
cardSlotsPanel.removeAll();
slotButtons.clear();
- int updatedSlots = 0;
- int errorSlots = 0;
-
for (int i = 1; i <= TOTAL_SLOTS; i++) {
final int slotId = i;
SlotStatus status = getSlotStatusFromManager(slotId);
@@ -476,10 +473,8 @@
// 娣诲姞璋冭瘯淇℃伅
Fkj slotInfo = slotManager.getSlotInfo(slotId);
if (slotInfo != null) {
- updatedSlots++;
} else {
System.err.println("鍗℃Ы " + slotId + " - 鑾峰彇淇℃伅澶辫触");
- errorSlots++;
}
JButton slotButton = new JButton(String.valueOf(slotId));
@@ -509,7 +504,7 @@
cardSlotsPanel.revalidate();
cardSlotsPanel.repaint();
- System.out.println("鍗℃Ы鏄剧ず鏇存柊瀹屾垚: " + updatedSlots + " 涓垚鍔�, " + errorSlots + " 涓け璐�");
+// System.out.println("鍗℃Ы鏄剧ず鏇存柊瀹屾垚: " + updatedSlots + " 涓垚鍔�, " + errorSlots + " 涓け璐�");
}
private Color brighterColor(Color color) {
@@ -572,7 +567,6 @@
if (panel.getComponentCount() >= 2) {
JLabel textLabel = (JLabel) panel.getComponent(1);
if (textLabel.getText().startsWith("涓插彛:")) {
- String statusText = lunxun.isSerialConnected() ? "姝e父" : "鏂紑";
Color statusColor = lunxun.isSerialConnected() ?
new Color(52, 152, 219) : new Color(231, 76, 60);
@@ -637,34 +631,6 @@
return "涓插彛瑙f瀽鍣ㄦ湭鍒濆鍖�";
}
- /**
- * 鍒涘缓缇庡寲鎸夐挳
- */
- private JButton createStyledButton(String text, Color color) {
- JButton button = new JButton(text);
- button.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
- button.setBackground(color);
- button.setForeground(Color.WHITE);
- button.setFocusPainted(false);
- button.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
- button.setCursor(new Cursor(Cursor.HAND_CURSOR));
-
- // 榧犳爣鎮仠鏁堟灉
- button.addMouseListener(new java.awt.event.MouseAdapter() {
- public void mouseEntered(java.awt.event.MouseEvent evt) {
- button.setBackground(brighterColor(color));
- }
-
- public void mouseExited(java.awt.event.MouseEvent evt) {
- button.setBackground(color);
- }
- });
-
- return button;
- }
-
-
-
/**
* 楠岃瘉鍙栧崱瀵嗙爜
*/
diff --git a/src/home/Homein.java b/src/home/Homein.java
index 4a9fe73..2ab0538 100644
--- a/src/home/Homein.java
+++ b/src/home/Homein.java
@@ -7,6 +7,8 @@
import chushihua.Chushihua;
import chushihua.SlotManager;
import chushihua.lunxun;
+import chushihua.lunxunzaixian;
+import jiekou.lunxunkazhuangtai;
public class Homein {
public static void main(String[] args) {
@@ -121,22 +123,20 @@
* 鍚姩搴旂敤绋嬪簭涓绘祦绋�
*/
private static void startApplication() {
- try {
- System.out.println("寮�濮嬪簲鐢ㄧ▼搴忎富娴佺▼...");
-
+ try {
// 3. 杩愯涓插彛杩炴帴瀵硅瘽妗嗭紝绛夊緟涓插彛杩炴帴鎴愬姛
- System.out.println("姝ラ3: 鍚姩涓插彛杩炴帴...");
boolean serialConnected = initializeSerialPort();
if (serialConnected) {
// 4. 涓插彛杩炴帴鎴愬姛鍚庯紝鍚姩杞
- System.out.println("姝ラ4: 鍚姩杞鏌ヨ...");
boolean pollingStarted = startPollingService();
if (pollingStarted) {
- // 5. 杩涘叆涓荤晫闈�
- System.out.println("姝ラ5: 鍚姩涓荤晫闈�...");
showMainInterface();
+ //鍚姩杞鍗$姸鎬佺粰鏈嶅姟鍣ㄥ彂鏁版嵁
+ lunxunkazhuangtai.startPolling();
+ //鍚姩鍦ㄧ嚎鐨勫崱鐘舵�佽疆璇�
+ lunxunzaixian.startOnlinePolling();
} else {
System.err.println("杞鏈嶅姟鍚姩澶辫触");
JOptionPane.showMessageDialog(null,
diff --git a/src/jiekou/HttpAPI.java b/src/jiekou/HttpAPI.java
new file mode 100644
index 0000000..8c9a6cc
--- /dev/null
+++ b/src/jiekou/HttpAPI.java
@@ -0,0 +1,129 @@
+package jiekou;
+
+public class HttpAPI {
+
+ static String url="http://192.168.100.96:8081/hxzkuwb/takeCard";//鍙栧崱鎺ュ彛
+ static String url1="http://192.168.100.96:8081/hxzkuwb/takeSuccess";//鍙栧崱鎴愬姛鎺ュ彛
+ static String url2="http://192.168.100.96:8081/hxzkuwb/saveCard";//杩樺崱鎺ュ彛
+
+ static String key="fghgf8fgj8fgf23ksdsd4sr5781ghj8l";
+
+ //----------------------------------------------------鍙栧崱鎺ュ彛----------------------------------------------------------------------------------
+ /**
+ * 璋冪敤鍙栧崱鎺ュ彛
+ * @param deviceId 璁惧ID
+ * @param faceId 浜鸿劯ID
+ * @param userId 鐢ㄦ埛ID
+ * @return 鍝嶅簲缁撴灉JSON瀛楃涓�
+ */
+ public static String callTakeCardApi(String apiUrl,String apiKey,String deviceId, String faceId, String userId) {
+ return TakeCardUtil.callTakeCardApi(apiUrl,apiKey,deviceId, faceId, userId);
+ }
+
+ //----------------------鍙栧崱杩斿洖鏁版嵁瑙f瀽--------------------------------
+ /**
+ * @param json 鏈嶅姟鍣ㄨ繑鍥炵殑JSON鏁版嵁
+ * @return 鍒ゆ柇鏄惁鍏佽鍙栧崱锛宼rue鍏佽锛宖alse涓嶅厑璁�
+ * */
+ public static Boolean isTakeCardAllowed(String json){
+ return TakeCardUtil.isTakeCardAllowed(json);
+ }
+ /**
+ * 浠庡搷搴斾腑鎻愬彇娑堟伅
+ * @param responseJson 鍝嶅簲JSON瀛楃涓�
+ * @return 娑堟伅瀛楃涓诧紝濡傛灉涓嶅瓨鍦ㄥ垯杩斿洖null
+ */
+ public static String extractMessage(String responseJson) {
+ return TakeCardUtil.extractJsonField(responseJson, "msg");
+ }
+ /**
+ * 浠庡搷搴斾腑鎻愬彇闂ㄥ彿
+ * @param responseJson 鍝嶅簲JSON瀛楃涓�
+ * @return 闂ㄥ彿瀛楃涓诧紝濡傛灉涓嶅瓨鍦ㄥ垯杩斿洖null
+ */
+ public static String extractDoorNo(String responseJson) {
+ return TakeCardUtil.extractJsonField(responseJson, "doorNo");
+ }
+
+ /**
+ * 浠庡搷搴斾腑鎻愬彇鍗″彿
+ * @param responseJson 鍝嶅簲JSON瀛楃涓�
+ * @return 闂ㄥ彿瀛楃涓诧紝濡傛灉涓嶅瓨鍦ㄥ垯杩斿洖null
+ */
+ public static String extractCardId(String responseJson) {
+ return TakeCardUtil.extractJsonField(responseJson, "cardID");
+ }
+
+ //----------------------------------------------------鍙栧崱鎴愬姛鎺ュ彛----------------------------------------------------------------------------------
+
+ /**
+ * 璋冪敤鍙栧崱鎴愬姛閫氱煡鎺ュ彛
+ *
+ * @param apiUrl 鎺ュ彛鐨刄RL鍦板潃
+ * @param doorNo 闂ㄥ彿(鍗佸叚杩涘埗)
+ * @param deviceId 璁惧ID
+ * @param cardId 鍗″彿(15瀛楄妭宸ヤ綔鍗″崱鍙�)
+ * @param faceId 浜鸿劯ID
+ * @param userId 鐢ㄦ埛ID
+ * @param apiKey API瀵嗛挜
+ * @return 鍝嶅簲缁撴灉JSON瀛楃涓�
+ */
+ public static String callTakeSuccess(
+ String apiUrl,
+ String apiKey,
+ String doorNo,
+ String deviceId,
+ String cardId,
+ String faceId,
+ String userId
+ ) {
+ return TakeCardSuccessUtil.callTakeSuccess(apiUrl,apiKey,doorNo,deviceId,cardId,faceId, userId);
+ }
+
+
+ //----------------------------------------------------杩樺崱鎺ュ彛----------------------------------------------------------------------------------
+ /**
+ * 璋冪敤杩樺崱鎺ュ彛
+ *
+ * @param apiUrl 鎺ュ彛鐨刄RL鍦板潃
+ * @param apiKey API瀵嗛挜
+ * @param doorNo 鏌滈棬鍙凤紙1鍒�60鐨�16杩涘埗鏁帮級
+ * @param deviceId 璁惧ID
+ * @param cardId 宸ヤ綔鍗″彿
+ * @param faceId 浜鸿劯Id
+ * @param userId 鐢ㄦ埛ID锛堢敤鎴峰敮涓�璇嗗埆鐮侊級
+ * @return 鍝嶅簲缁撴灉JSON瀛楃涓�
+ */
+ public static String callReturnCard(
+ String apiUrl,
+ String apiKey,
+ String doorNo,
+ String deviceId,
+ String cardId,
+ Integer faceId,
+ String userId
+ ) {
+ return ReturnCardUtil.callReturnCard(apiUrl,apiKey,doorNo,deviceId,cardId,faceId,userId);
+ }
+
+
+ /**
+ * 鍒ゆ柇鍝嶅簲鏄惁鍏佽杩樺崱
+ * @param responseJson 鍝嶅簲JSON瀛楃涓�
+ * @return true=鍏佽鍙栧崱, false=涓嶅厑璁�
+ */
+ public static Boolean isReturnSuccess(String responseJson){
+ return ReturnCardUtil.isReturnSuccess(responseJson);
+ }
+
+ /**
+ * 浠庢崲鍗″搷搴斾腑鎻愬彇娑堟伅
+ * @param responseJson 鍝嶅簲JSON瀛楃涓�
+ * @return 娑堟伅瀛楃涓诧紝濡傛灉涓嶅瓨鍦ㄥ垯杩斿洖null
+ */
+ public static String ReturnExtractMessage(String responseJson) {
+ return ReturnCardUtil.getResponseMessage(responseJson);
+ }
+
+
+}
diff --git a/src/jiekou/ReturnCardUtil.java b/src/jiekou/ReturnCardUtil.java
new file mode 100644
index 0000000..47a705f
--- /dev/null
+++ b/src/jiekou/ReturnCardUtil.java
@@ -0,0 +1,230 @@
+package jiekou;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+/**
+ * 杩樺崱鎺ュ彛宸ュ叿绫�
+ * 浣跨敤Slf4j鏃ュ織杈撳嚭锛屼粎鏀寔鍚屾澶勭悊
+ */
+public class ReturnCardUtil {
+
+ private static final Logger logger = LoggerFactory.getLogger(ReturnCardUtil.class);
+
+ // 杩炴帴瓒呮椂鍜岃鍙栬秴鏃舵椂闂�
+ private static final int CONNECT_TIMEOUT = 5000;
+ private static final int READ_TIMEOUT = 10000;
+
+ /**
+ * 璋冪敤杩樺崱鎺ュ彛
+ *
+ * @param apiUrl 鎺ュ彛鐨刄RL鍦板潃
+ * @param apiKey API瀵嗛挜
+ * @param doorNo 鏌滈棬鍙凤紙1鍒�60鐨�16杩涘埗鏁帮級
+ * @param deviceId 璁惧ID
+ * @param cardId 宸ヤ綔鍗″彿
+ * @param faceId 浜鸿劯Id
+ * @param userId 鐢ㄦ埛ID锛堢敤鎴峰敮涓�璇嗗埆鐮侊級
+ * @return 鍝嶅簲缁撴灉JSON瀛楃涓�
+ */
+ public static String callReturnCard(
+ String apiUrl,
+ String apiKey,
+ String doorNo,
+ String deviceId,
+ String cardId,
+ Integer faceId,
+ String userId
+ ) {
+
+ HttpURLConnection connection = null;
+ BufferedReader reader = null;
+
+ try {
+ // 鏋勫缓URL
+ URL url = new URL(apiUrl);
+ connection = (HttpURLConnection) url.openConnection();
+
+ // 璁剧疆杩炴帴鍙傛暟
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/json");
+ connection.setRequestProperty("apiKey", apiKey);
+ connection.setConnectTimeout(CONNECT_TIMEOUT);
+ connection.setReadTimeout(READ_TIMEOUT);
+ connection.setDoOutput(true);
+
+ // 鏋勫缓璇锋眰浣�
+ String requestBody = buildRequestBody(doorNo, deviceId, cardId, faceId, userId);
+ logger.info("杩樺崱鎺ュ彛璇锋眰URL: {}", apiUrl);
+ logger.info("杩樺崱鎺ュ彛璇锋眰鍙傛暟: {}", requestBody);
+
+ // 鍙戦�佽姹備綋
+ try (OutputStream os = connection.getOutputStream()) {
+ byte[] input = requestBody.getBytes("utf-8");
+ os.write(input, 0, input.length);
+ }
+
+ // 鑾峰彇鍝嶅簲鐮�
+ int responseCode = connection.getResponseCode();
+ logger.info("杩樺崱鎺ュ彛鍝嶅簲鐮�: {}", responseCode);
+
+ // 璇诲彇鍝嶅簲鍐呭
+ StringBuilder response = new StringBuilder();
+ if (responseCode == HttpURLConnection.HTTP_OK) {
+ reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
+ } else {
+ reader = new BufferedReader(new InputStreamReader(connection.getErrorStream(), "utf-8"));
+ }
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ response.append(line);
+ }
+
+ String responseBody = response.toString();
+ logger.info("杩樺崱鎺ュ彛鍝嶅簲: {}", responseBody);
+
+ return responseBody;
+
+ } catch (Exception e) {
+ logger.error("璋冪敤杩樺崱鎺ュ彛鍙戠敓寮傚父", e);
+ return buildErrorResponse("鎺ュ彛璋冪敤寮傚父: " + e.getMessage());
+ } finally {
+ // 鍏抽棴璧勬簮
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (Exception e) {
+ logger.error("鍏抽棴BufferedReader澶辫触", e);
+ }
+ }
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+ }
+
+ /**
+ * 鏋勫缓璇锋眰浣揓SON
+ *
+ * @param doorNo 鏌滈棬鍙�
+ * @param deviceId 璁惧ID
+ * @param cardId 宸ヤ綔鍗″彿
+ * @param faceId 浜鸿劯Id锛堝彲涓簄ull锛�
+ * @param userId 鐢ㄦ埛ID
+ * @return JSON鏍煎紡鐨勮姹備綋
+ */
+ private static String buildRequestBody(String doorNo, String deviceId, String cardId, Integer faceId, String userId) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ sb.append("\"doorNo\":\"").append(doorNo).append("\",");
+ sb.append("\"deviceId\":\"").append(deviceId).append("\",");
+ sb.append("\"cardId\":\"").append(cardId).append("\",");
+
+ // faceId鏄潪蹇呭~瀛楁锛屽鏋滀负null鍒欎笉鍖呭惈鍦ㄨ姹備綋涓�
+ if (faceId != null) {
+ sb.append("\"faceId\":").append(faceId).append(",");
+ }
+
+ sb.append("\"userId\":\"").append(userId).append("\"");
+ sb.append("}");
+
+ return sb.toString();
+ }
+
+ /**
+ * 鏋勫缓閿欒鍝嶅簲
+ *
+ * @param errorMsg 閿欒淇℃伅
+ * @return JSON鏍煎紡鐨勯敊璇搷搴�
+ */
+ private static String buildErrorResponse(String errorMsg) {
+ return "{\"code\":\"500\",\"status\":\"0\",\"msg\":\"" + errorMsg + "\"}";
+ }
+
+ /**
+ * 鍒ゆ柇杩樺崱鏄惁鎴愬姛
+ *
+ * @param responseJson 鍝嶅簲JSON瀛楃涓�
+ * @return true=鎴愬姛, false=澶辫触
+ */
+ public static boolean isReturnSuccess(String responseJson) {
+ try {
+ if (responseJson != null && responseJson.contains("\"code\"") && responseJson.contains("\"status\"")) {
+ // 妫�鏌ode鏄惁涓�200
+ int codeIndex = responseJson.indexOf("\"code\"");
+ if (codeIndex != -1) {
+ int codeColonIndex = responseJson.indexOf(":", codeIndex);
+ int codeCommaIndex = responseJson.indexOf(",", codeColonIndex);
+ if (codeCommaIndex == -1) {
+ codeCommaIndex = responseJson.indexOf("}", codeColonIndex);
+ }
+
+ if (codeColonIndex != -1 && codeCommaIndex != -1) {
+ String codeValue = responseJson.substring(codeColonIndex + 1, codeCommaIndex).trim();
+ codeValue = codeValue.replace("\"", "").replace("'", "");
+
+ // 濡傛灉code涓嶆槸200锛岀洿鎺ヨ繑鍥炲け璐�
+ if (!"200".equals(codeValue)) {
+ return false;
+ }
+ }
+ }
+
+ // 妫�鏌tatus鏄惁涓�1
+ int statusIndex = responseJson.indexOf("\"status\"");
+ if (statusIndex != -1) {
+ int colonIndex = responseJson.indexOf(":", statusIndex);
+ int commaIndex = responseJson.indexOf(",", colonIndex);
+ int endIndex = responseJson.indexOf("}", colonIndex);
+ if (commaIndex == -1 || commaIndex > endIndex) {
+ commaIndex = endIndex;
+ }
+
+ if (colonIndex != -1 && commaIndex != -1) {
+ String statusValue = responseJson.substring(colonIndex + 1, commaIndex).trim();
+ statusValue = statusValue.replace("\"", "").replace("'", "");
+ return "1".equals(statusValue);
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.error("瑙f瀽杩樺崱鎺ュ彛鍝嶅簲鐘舵�佸け璐�", e);
+ }
+ return false;
+ }
+
+ /**
+ * 鑾峰彇鍝嶅簲娑堟伅
+ *
+ * @param responseJson 鍝嶅簲JSON瀛楃涓�
+ * @return 娑堟伅鍐呭锛屽鏋滆В鏋愬け璐ヨ繑鍥炵┖瀛楃涓�
+ */
+ public static String getResponseMessage(String responseJson) {
+ try {
+ if (responseJson != null && responseJson.contains("\"msg\"")) {
+ int msgIndex = responseJson.indexOf("\"msg\"");
+ if (msgIndex != -1) {
+ int colonIndex = responseJson.indexOf(":", msgIndex);
+ int commaIndex = responseJson.indexOf(",", colonIndex);
+ int endIndex = responseJson.indexOf("}", colonIndex);
+ if (commaIndex == -1 || commaIndex > endIndex) {
+ commaIndex = endIndex;
+ }
+
+ if (colonIndex != -1 && commaIndex != -1) {
+ String msgValue = responseJson.substring(colonIndex + 1, commaIndex).trim();
+ return msgValue.replace("\"", "").replace("'", "");
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.error("瑙f瀽杩樺崱鎺ュ彛鍝嶅簲娑堟伅澶辫触", e);
+ }
+ return "";
+ }
+}
\ No newline at end of file
diff --git a/src/jiekou/TCPApi.java b/src/jiekou/TCPApi.java
new file mode 100644
index 0000000..ca204c3
--- /dev/null
+++ b/src/jiekou/TCPApi.java
@@ -0,0 +1,57 @@
+package jiekou;
+
+import java.util.Map;
+
+public class TCPApi {
+
+// public static void main(String[] args) {
+// // 鍒涘缓瀹㈡埛绔�
+// TcpClientUtil client = new TcpClientUtil();
+//
+// // 杩炴帴鏈嶅姟鍣�
+// boolean connected = client.connect("192.168.100.96", 8889);
+// if (connected) {
+// // 鐧诲綍
+// Map<String, Object> loginResponse = client.sendLoginRequest("device001");
+//
+// // 鍚姩娑堟伅鐩戝惉
+// client.startMessageListener(new TcpClientUtil.MessageListener() {
+// @Override
+// public void onMessageReceived(String rawMessage, Map<String, Object> parsedMessage) {
+// String code = String.valueOf(parsedMessage.get("code"));
+// String cmd = (String) parsedMessage.get("cmd");
+// Object data = parsedMessage.get("data");
+//
+// // 鏍规嵁涓嶅悓鐨勫懡浠よ繘琛屽鐞�
+// switch (code) {
+// case "102": // 鍒犻櫎浜哄憳
+// if ("delete".equals(cmd)) {
+// // 涓氬姟澶勭悊...
+// client.sendDeleteAck((String) data);
+// }
+// break;
+// case "103": // 寮�閿�
+// if ("openDoor".equals(cmd)) {
+// // 涓氬姟澶勭悊...
+// client.sendOpenDoorAck((String) data);
+// }
+// break;
+// case "104": // 鍗囩骇
+// if ("upDate".equals(cmd)) {
+// // 涓氬姟澶勭悊...
+// client.sendUpdateAck((String) data);
+// }
+// break;
+// default:
+// System.out.println("鏈煡鍛戒护: code=" + code + ", cmd=" + cmd);
+// }
+// }
+//
+//
+// });
+//
+// /* // 璇锋眰浜哄憳鏁版嵁
+// List<Map<String, Object>> personList = client.requestPersonData("device001");*/
+// }
+// }
+}
diff --git a/src/jiekou/TakeCardSuccessUtil.java b/src/jiekou/TakeCardSuccessUtil.java
new file mode 100644
index 0000000..b022204
--- /dev/null
+++ b/src/jiekou/TakeCardSuccessUtil.java
@@ -0,0 +1,171 @@
+package jiekou;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+/**
+ * 鍙栧崱鎴愬姛閫氱煡宸ュ叿绫�
+ * 浣跨敤Slf4j鏃ュ織杈撳嚭锛屼粎鏀寔鍚屾澶勭悊
+ */
+public class TakeCardSuccessUtil {
+
+ private static final Logger logger = LoggerFactory.getLogger(TakeCardSuccessUtil.class);
+
+ // 杩炴帴瓒呮椂鍜岃鍙栬秴鏃舵椂闂�
+ private static final int CONNECT_TIMEOUT = 5000;
+ private static final int READ_TIMEOUT = 10000;
+
+ /**
+ * 璋冪敤鍙栧崱鎴愬姛閫氱煡鎺ュ彛
+ *
+ * @param apiUrl 鎺ュ彛鐨刄RL鍦板潃
+ * @param doorNo 闂ㄥ彿(鍗佸叚杩涘埗)
+ * @param deviceId 璁惧ID
+ * @param cardId 鍗″彿(15瀛楄妭宸ヤ綔鍗″崱鍙�)
+ * @param faceId 浜鸿劯ID
+ * @param userId 鐢ㄦ埛ID
+ * @param apiKey API瀵嗛挜
+ * @return 鍝嶅簲缁撴灉JSON瀛楃涓�
+ */
+ @SuppressWarnings("deprecation")
+ public static String callTakeSuccess(
+ String apiUrl,
+ String apiKey,
+ String doorNo,
+ String deviceId,
+ String cardId,
+ String faceId,
+ String userId
+ ) {
+
+ HttpURLConnection connection = null;
+ BufferedReader reader = null;
+
+ try {
+ // 鏋勫缓URL
+ URL url = new URL(apiUrl);
+ connection = (HttpURLConnection) url.openConnection();
+
+ // 璁剧疆杩炴帴鍙傛暟
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/json");
+ connection.setRequestProperty("apiKey", apiKey);
+ connection.setConnectTimeout(CONNECT_TIMEOUT);
+ connection.setReadTimeout(READ_TIMEOUT);
+ connection.setDoOutput(true);
+
+ // 鏋勫缓璇锋眰浣�
+ String requestBody = buildRequestBody(doorNo, deviceId, cardId, faceId, userId);
+ logger.info("鍙栧崱鎴愬姛閫氱煡鎺ュ彛璇锋眰URL: {}", apiUrl);
+ logger.info("鍙栧崱鎴愬姛閫氱煡鎺ュ彛璇锋眰鍙傛暟: {}", requestBody);
+
+ // 鍙戦�佽姹備綋
+ try (OutputStream os = connection.getOutputStream()) {
+ byte[] input = requestBody.getBytes("utf-8");
+ os.write(input, 0, input.length);
+ }
+
+ // 鑾峰彇鍝嶅簲鐮�
+ int responseCode = connection.getResponseCode();
+ logger.info("鍙栧崱鎴愬姛閫氱煡鎺ュ彛鍝嶅簲鐮�: {}", responseCode);
+
+ // 璇诲彇鍝嶅簲鍐呭
+ StringBuilder response = new StringBuilder();
+ if (responseCode == HttpURLConnection.HTTP_OK) {
+ reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
+ } else {
+ reader = new BufferedReader(new InputStreamReader(connection.getErrorStream(), "utf-8"));
+ }
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ response.append(line);
+ }
+
+ String responseBody = response.toString();
+ logger.info("鍙栧崱鎴愬姛閫氱煡鎺ュ彛鍝嶅簲: {}", responseBody);
+
+ return responseBody;
+
+ } catch (Exception e) {
+ logger.error("璋冪敤鍙栧崱鎴愬姛閫氱煡鎺ュ彛鍙戠敓寮傚父", e);
+ return buildErrorResponse("鎺ュ彛璋冪敤寮傚父: " + e.getMessage());
+ } finally {
+ // 鍏抽棴璧勬簮
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (Exception e) {
+ logger.error("鍏抽棴BufferedReader澶辫触", e);
+ }
+ }
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+ }
+
+ /**
+ * 鏋勫缓璇锋眰浣揓SON
+ *
+ * @param doorNo 闂ㄥ彿
+ * @param deviceId 璁惧ID
+ * @param cardId 鍗″彿
+ * @param faceId 浜鸿劯ID
+ * @param userId 鐢ㄦ埛ID
+ * @return JSON鏍煎紡鐨勮姹備綋
+ */
+ private static String buildRequestBody(String doorNo, String deviceId, String cardId, String faceId, String userId) {
+ return "{\"doorNo\":\"" + doorNo +
+ "\",\"deviceId\":\"" + deviceId +
+ "\",\"cardId\":\"" + cardId +
+ "\",\"faceId\":\"" + faceId +
+ "\",\"userId\":\"" + userId + "\"}";
+ }
+
+ /**
+ * 鏋勫缓閿欒鍝嶅簲
+ *
+ * @param errorMsg 閿欒淇℃伅
+ * @return JSON鏍煎紡鐨勯敊璇搷搴�
+ */
+ private static String buildErrorResponse(String errorMsg) {
+ return "{\"status\":\"0\",\"error\":\"" + errorMsg + "\"}";
+ }
+
+ /**
+ * 鍒ゆ柇鍝嶅簲鏄惁鎴愬姛
+ *
+ * @param responseJson 鍝嶅簲JSON瀛楃涓�
+ * @return true=鎴愬姛, false=澶辫触
+ */
+ public static boolean isTakeSuccess(String responseJson) {
+ try {
+ if (responseJson != null && responseJson.contains("\"status\"")) {
+ int statusIndex = responseJson.indexOf("\"status\"");
+ if (statusIndex != -1) {
+ // 鏌ユ壘status鍊�
+ int colonIndex = responseJson.indexOf(":", statusIndex);
+ int commaIndex = responseJson.indexOf(",", colonIndex);
+ int endIndex = responseJson.indexOf("}", colonIndex);
+ if (commaIndex == -1 || commaIndex > endIndex) {
+ commaIndex = endIndex;
+ }
+
+ if (colonIndex != -1 && commaIndex != -1) {
+ String statusValue = responseJson.substring(colonIndex + 1, commaIndex).trim();
+ statusValue = statusValue.replace("\"", "").replace("'", "");
+ return "1".equals(statusValue);
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.error("瑙f瀽鍙栧崱鎴愬姛閫氱煡鍝嶅簲鐘舵�佸け璐�", e);
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/src/jiekou/TakeCardUtil.java b/src/jiekou/TakeCardUtil.java
new file mode 100644
index 0000000..f8085f6
--- /dev/null
+++ b/src/jiekou/TakeCardUtil.java
@@ -0,0 +1,184 @@
+package jiekou;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 鍙栧崱鎺ュ彛宸ュ叿绫� - 绠�鍖栫増鏈�
+ * 涓嶄娇鐢ㄥ閮↗SON搴擄紝涓嶅寘鍚噸璇曢�昏緫
+ */
+public class TakeCardUtil {
+
+ // 閰嶇疆灞炴��
+ private static final Logger logger = LoggerFactory.getLogger(TakeCardUtil.class);
+ private static final int CONNECT_TIMEOUT = 5000;
+ private static final int READ_TIMEOUT = 10000;
+
+ /**
+ * 璋冪敤鍙栧崱鎺ュ彛
+ * @param deviceId 璁惧ID
+ * @param faceId 浜鸿劯ID
+ * @param userId 鐢ㄦ埛ID
+ * @return 鍝嶅簲缁撴灉JSON瀛楃涓�
+ */
+ protected static String callTakeCardApi(
+ String apiUrl,String apiKey,
+ String deviceId, String faceId, String userId) {
+ HttpURLConnection connection = null;
+ BufferedReader reader = null;
+
+ try {
+ // 鍒涘缓URL杩炴帴
+ URL url = new URL(apiUrl);
+ connection = (HttpURLConnection) url.openConnection();
+
+ // 璁剧疆杩炴帴鍙傛暟
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/json");
+ connection.setRequestProperty("apiKey", apiKey);
+ connection.setConnectTimeout(CONNECT_TIMEOUT);
+ connection.setReadTimeout(READ_TIMEOUT);
+ connection.setDoOutput(true);
+
+ // 鏋勫缓璇锋眰浣�
+ String requestBody = buildRequestBody(deviceId, faceId, userId);
+ logger.info("鍙栧崱鎺ュ彛璇锋眰鍙傛暟: {}", requestBody);
+
+ // 鍙戦�佽姹備綋
+ try (OutputStream os = connection.getOutputStream()) {
+ byte[] input = requestBody.getBytes("utf-8");
+ os.write(input, 0, input.length);
+ }
+
+ // 鑾峰彇鍝嶅簲鐮�
+ int responseCode = connection.getResponseCode();
+ logger.info("鍙栧崱鎺ュ彛鍝嶅簲鐮�: {}", responseCode);
+
+ // 璇诲彇鍝嶅簲鍐呭
+ StringBuilder response = new StringBuilder();
+ if (responseCode == HttpURLConnection.HTTP_OK) {
+ reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
+ } else {
+ reader = new BufferedReader(new InputStreamReader(connection.getErrorStream(), "utf-8"));
+ }
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ response.append(line);
+ }
+
+ String responseBody = response.toString();
+ logger.info("鍙栧崱鎺ュ彛鍝嶅簲: {}", responseBody);
+
+ return responseBody;
+
+ } catch (Exception e) {
+ logger.error("璋冪敤鍙栧崱鎺ュ彛鍙戠敓寮傚父", e);
+ return buildErrorResponse("鎺ュ彛璋冪敤寮傚父: " + e.getMessage());
+ } finally {
+ // 鍏抽棴璧勬簮
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (Exception e) {
+ logger.error("鍏抽棴BufferedReader澶辫触", e);
+ }
+ }
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+ }
+
+ /**
+ * 鏋勫缓璇锋眰浣揓SON
+ * @param deviceId 璁惧ID
+ * @param faceId 浜鸿劯ID
+ * @param userId 鐢ㄦ埛ID
+ * @return JSON鏍煎紡鐨勮姹備綋
+ */
+ private static String buildRequestBody(String deviceId, String faceId, String userId) {
+ return "{\"deviceId\":\"" + deviceId +
+ "\",\"faceId\":\"" + faceId +
+ "\",\"userId\":\"" + userId + "\"}";
+ }
+
+ /**
+ * 鏋勫缓閿欒鍝嶅簲
+ * @param errorMsg 閿欒淇℃伅
+ * @return JSON鏍煎紡鐨勯敊璇搷搴�
+ */
+ private static String buildErrorResponse(String errorMsg) {
+ return "{\"code\":\"500\",\"status\":\"2\",\"msg\":\"" + errorMsg + "\"}";
+ }
+
+ /**
+ * 鍒ゆ柇鍝嶅簲鏄惁鍏佽鍙栧崱
+ * @param responseJson 鍝嶅簲JSON瀛楃涓�
+ * @return true=鍏佽鍙栧崱, false=涓嶅厑璁�
+ */
+ public static boolean isTakeCardAllowed(String responseJson) {
+ try {
+ // 绠�鍗曡В鏋恠tatus瀛楁
+ if (responseJson != null && responseJson.contains("\"status\"")) {
+ int statusIndex = responseJson.indexOf("\"status\"");
+ if (statusIndex != -1) {
+ // 鏌ユ壘status鍊�
+ int colonIndex = responseJson.indexOf(":", statusIndex);
+ int commaIndex = responseJson.indexOf(",", colonIndex);
+ int endIndex = responseJson.indexOf("}", colonIndex);
+ if (commaIndex == -1 || commaIndex > endIndex) {
+ commaIndex = endIndex;
+ }
+
+ if (colonIndex != -1 && commaIndex != -1) {
+ String statusValue = responseJson.substring(colonIndex + 1, commaIndex).trim();
+ statusValue = statusValue.replace("\"", "").replace("'", "");
+ return "1".equals(statusValue);
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.error("瑙f瀽鍝嶅簲鐘舵�佸け璐�", e);
+ }
+ return false;
+ }
+
+ /**
+ * 浠嶫SON瀛楃涓蹭腑鎻愬彇鎸囧畾瀛楁鐨勫��
+ * @param json JSON瀛楃涓�
+ * @param fieldName 瀛楁鍚�
+ * @return 瀛楁鍊硷紝濡傛灉涓嶅瓨鍦ㄥ垯杩斿洖null
+ */
+ protected static String extractJsonField(String json, String fieldName) {
+ try {
+ if (json != null && json.contains("\"" + fieldName + "\"")) {
+ int fieldIndex = json.indexOf("\"" + fieldName + "\"");
+ if (fieldIndex != -1) {
+ // 鏌ユ壘瀛楁鍊�
+ int colonIndex = json.indexOf(":", fieldIndex);
+ int commaIndex = json.indexOf(",", colonIndex);
+ int endIndex = json.indexOf("}", colonIndex);
+ if (commaIndex == -1 || commaIndex > endIndex) {
+ commaIndex = endIndex;
+ }
+
+ if (colonIndex != -1 && commaIndex != -1) {
+ String fieldValue = json.substring(colonIndex + 1, commaIndex).trim();
+ // 鍘婚櫎寮曞彿
+ if (fieldValue.startsWith("\"") && fieldValue.endsWith("\"")) {
+ fieldValue = fieldValue.substring(1, fieldValue.length() - 1);
+ }
+ return fieldValue.isEmpty() ? null : fieldValue;
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.error("鎻愬彇瀛楁 {} 澶辫触", fieldName, e);
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/jiekou/TcpClientUtil.java b/src/jiekou/TcpClientUtil.java
new file mode 100644
index 0000000..eb1926f
--- /dev/null
+++ b/src/jiekou/TcpClientUtil.java
@@ -0,0 +1,595 @@
+package jiekou;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.net.Socket;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * TCP瀹㈡埛绔伐鍏风被
+ * 瀹炵幇鍙戝崱鏈轰笌鏈嶅姟鍣ㄧ殑鎵�鏈夐�氫俊鎺ュ彛
+ */
+public class TcpClientUtil {
+ private static final Logger logger = LoggerFactory.getLogger(TcpClientUtil.class);
+
+ private Socket socket;
+ private OutputStream outputStream;
+ private InputStream inputStream;
+ private BufferedReader reader;
+ private volatile boolean running = false;
+ private MessageListener messageListener;
+
+ // 閲嶈繛鐩稿叧閰嶇疆
+ private String serverIp;
+ private int serverPort;
+ private String deviceId;
+ private final AtomicBoolean reconnecting = new AtomicBoolean(false);
+ private static final int RECONNECT_INTERVAL = 3000; // 閲嶈繛闂撮殧3绉�
+
+ // JSON瑙f瀽妯″紡
+ private static final Pattern JSON_PATTERN = Pattern.compile("\"([^\"]+)\"\\s*:\\s*(\"[^\"]*\"|[^,\\}\\s]*)");
+ private static final Pattern ARRAY_PATTERN = Pattern.compile("\\{([^}]*)\\}");
+
+ /**
+ * 杩炴帴TCP鏈嶅姟鍣�
+ * @param ip 鏈嶅姟鍣↖P鍦板潃
+ * @param port 鏈嶅姟鍣ㄧ鍙�
+ * @return 杩炴帴鏄惁鎴愬姛
+ */
+ public boolean connect(String ip, int port) {
+ try {
+ // 淇濆瓨杩炴帴鍙傛暟鐢ㄤ簬閲嶈繛
+ this.serverIp = ip;
+ this.serverPort = port;
+
+ // 1. 鍒涘缓Socket杩炴帴鏈嶅姟鍣�
+ this.socket = new Socket(ip, port);
+ // 绉婚櫎瓒呮椂璁剧疆锛岃鐩戝惉绾跨▼鍙互鏃犻檺绛夊緟
+ socket.setSoTimeout(0);
+
+ // 2. 鑾峰彇杈撳叆杈撳嚭娴�
+ this.outputStream = socket.getOutputStream();
+ this.inputStream = socket.getInputStream();
+ this.reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+
+ logger.info("鎴愬姛杩炴帴鍒版湇鍔″櫒: {}:{}", ip, port);
+ reconnecting.set(false); // 閲嶇疆閲嶈繛鐘舵��
+ return true;
+
+ } catch (IOException e) {
+ logger.error("TCP杩炴帴寮傚父: {}", e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 杩炴帴骞剁櫥褰曟湇鍔″櫒
+ * @param ip 鏈嶅姟鍣↖P鍦板潃
+ * @param port 鏈嶅姟鍣ㄧ鍙�
+ * @param deviceId 璁惧ID
+ * @return 鐧诲綍鏄惁鎴愬姛
+ */
+ public boolean connectAndLogin(String ip, int port, String deviceId) {
+ this.deviceId = deviceId; // 淇濆瓨璁惧ID鐢ㄤ簬閲嶈繛鍚庨噸鏂扮櫥褰�
+ if (!connect(ip, port)) {
+ return false;
+ }
+
+ Map<String, Object> response = sendLoginRequest(deviceId);
+ return response != null &&
+ "logined".equals(response.get("cmd")) &&
+ "100".equals(String.valueOf(response.get("code")));
+ }
+
+ /**
+ * 鍙戦�佺櫥褰曡姹�
+ * @param deviceId 璁惧ID
+ * @return 鐧诲綍鍝嶅簲鏁版嵁
+ */
+ public Map<String, Object> sendLoginRequest(String deviceId) {
+ try {
+ // 鏋勫缓鐧诲綍璇锋眰JSON
+ String loginRequest = buildLoginRequestJson(deviceId);
+ logger.debug("鍙戦�佺櫥褰曡姹�: {}", loginRequest);
+
+ // 鍙戦�佺櫥褰曡姹�
+ boolean sendSuccess = sendMessage(loginRequest);
+ if (!sendSuccess) {
+ return null;
+ }
+
+ // 璇诲彇鏈嶅姟鍣ㄥ搷搴�
+ String response = reader.readLine();
+ logger.info("鏀跺埌鏈嶅姟鍣ㄧ櫥褰曞搷搴�: {}", response);
+
+ // 瑙f瀽鍝嶅簲骞惰繑鍥�
+ return parseJson(response);
+
+ } catch (IOException e) {
+ logger.error("鐧诲綍璇锋眰寮傚父: {}", e.getMessage(), e);
+ return null;
+ }
+ }
+
+ /**
+ * 璇锋眰浜哄憳鏁版嵁
+ * @param deviceId 璁惧ID
+ * @return 浜哄憳鏁版嵁鍒楄〃
+ */
+ public List<Map<String, Object>> requestPersonData(String deviceId) {
+ try {
+ // 鏋勫缓浜哄憳鏁版嵁璇锋眰JSON
+ String batchGetRequest = buildBatchGetRequestJson(deviceId);
+ logger.debug("鍙戦�佷汉鍛樻暟鎹姹�: {}", batchGetRequest);
+
+ // 鍙戦�佽姹�
+ boolean sendSuccess = sendMessage(batchGetRequest);
+ if (!sendSuccess) {
+ return null;
+ }
+
+ // 璇诲彇鏈嶅姟鍣ㄥ搷搴旓紙浜哄憳鏁版嵁锛�
+ String response = reader.readLine();
+ logger.info("鏀跺埌浜哄憳鏁版嵁: {}", response);
+
+ // 瑙f瀽鍝嶅簲
+ Map<String, Object> responseMap = parseJson(response);
+ if ("send".equals(responseMap.get("cmd")) && "101".equals(String.valueOf(responseMap.get("code")))) {
+ // 瑙f瀽浜哄憳鏁版嵁
+ String dataStr = (String) responseMap.get("data");
+ List<Map<String, Object>> personList = parsePersonDataArray(dataStr);
+
+ // 鍙戦�佹垚鍔熷簲绛�
+ sendSentAck();
+
+ return personList;
+ }
+
+ return null;
+
+ } catch (IOException e) {
+ logger.error("璇锋眰浜哄憳鏁版嵁寮傚父: {}", e.getMessage(), e);
+ return null;
+ }
+ }
+
+ /**
+ * 鍙戦�佷汉鍛樻暟鎹帴鏀舵垚鍔熷簲绛�
+ */
+ public boolean sendSentAck() {
+ try {
+ String ackJson = "{\"code\":101,\"cmd\":\"sent\",\"data\":null}";
+ return sendMessage(ackJson);
+ } catch (Exception e) {
+ logger.error("鍙戦�佹垚鍔熷簲绛斿紓甯�: {}", e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 鍙戦�佸垹闄や汉鍛樻垚鍔熷簲绛�
+ * @param userId 鐢ㄦ埛ID
+ * @return 鍙戦�佹槸鍚︽垚鍔�
+ */
+ public boolean sendDeleteAck(String userId) {
+ try {
+ String ackJson = "{\"code\":102,\"cmd\":\"deleted\",\"data\":null}";
+ boolean success = sendMessage(ackJson);
+ if (success) {
+ logger.info("鍙戦�佸垹闄や汉鍛樻垚鍔熷簲绛旓紝鐢ㄦ埛ID: {}", userId);
+ }
+ return success;
+ } catch (Exception e) {
+ logger.error("鍙戦�佸垹闄や汉鍛樻垚鍔熷簲绛斿紓甯�: {}", e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 鍙戦�佸紑閿佹垚鍔熷簲绛�
+ * @param doorNo 闂ㄧ紪鍙�
+ * @return 鍙戦�佹槸鍚︽垚鍔�
+ */
+ public boolean sendOpenDoorAck(String doorNo) {
+ try {
+ String ackJson = "{\"code\":103,\"cmd\":\"opened\",\"data\":null}";
+ boolean success = sendMessage(ackJson);
+ if (success) {
+ logger.info("鍙戦�佸紑閿佹垚鍔熷簲绛旓紝闂ㄧ紪鍙�: {}", doorNo);
+ }
+ return success;
+ } catch (Exception e) {
+ logger.error("鍙戦�佸紑閿佹垚鍔熷簲绛斿紓甯�: {}", e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 鍙戦�佸崌绾ф垚鍔熷簲绛�
+ * @param updateUrl 鍗囩骇鏂囦欢URL
+ * @return 鍙戦�佹槸鍚︽垚鍔�
+ */
+ public boolean sendUpdateAck(String updateUrl) {
+ try {
+ String ackJson = "{\"code\":104,\"cmd\":\"upDated\",\"data\":null}";
+ boolean success = sendMessage(ackJson);
+ if (success) {
+ logger.info("鍙戦�佸崌绾ф垚鍔熷簲绛旓紝鍗囩骇URL: {}", updateUrl);
+ }
+ return success;
+ } catch (Exception e) {
+ logger.error("鍙戦�佸崌绾ф垚鍔熷簲绛斿紓甯�: {}", e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 鍙戦�佽嚜瀹氫箟鍛戒护
+ * @param code 鍛戒护浠g爜
+ * @param cmd 鍛戒护绫诲瀷
+ * @param data 鏁版嵁
+ * @return 鍙戦�佹槸鍚︽垚鍔�
+ */
+ public boolean sendCommand(String code, String cmd, String data) {
+ try {
+ String json = buildCommandJson(code, cmd, data);
+ boolean success = sendMessage(json);
+ if (success) {
+ logger.debug("鍙戦�佸懡浠�: {}", json);
+ }
+ return success;
+ } catch (Exception e) {
+ logger.error("鍙戦�佸懡浠ゅ紓甯�: {}", e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 閫氱敤娑堟伅鍙戦�佹柟娉�
+ * @param message 瑕佸彂閫佺殑娑堟伅
+ * @return 鍙戦�佹槸鍚︽垚鍔�
+ */
+ public boolean sendMessage(String message) {
+ if (!isConnected()) {
+ logger.error("杩炴帴鏈缓绔嬶紝鏃犳硶鍙戦�佹秷鎭�");
+ return false;
+ }
+
+ try {
+ outputStream.write((message + "\n").getBytes(StandardCharsets.UTF_8));
+ outputStream.flush();
+ return true;
+ } catch (IOException e) {
+ logger.error("鍙戦�佹秷鎭紓甯�: {}", e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 璇诲彇鏈嶅姟鍣ㄥ搷搴�
+ * @return 鏈嶅姟鍣ㄥ搷搴旀暟鎹�
+ */
+ public String readResponse() {
+ try {
+ return reader.readLine();
+ } catch (IOException e) {
+ logger.error("璇诲彇鍝嶅簲寮傚父: {}", e.getMessage(), e);
+ return null;
+ }
+ }
+
+ /**
+ * 璇诲彇骞惰В鏋愭湇鍔″櫒鍝嶅簲
+ * @return 瑙f瀽鍚庣殑鍝嶅簲Map
+ */
+ public Map<String, Object> readAndParseResponse() {
+ String response = readResponse();
+ if (response != null) {
+ return parseJson(response);
+ }
+ return null;
+ }
+
+ /**
+ * 鏂嚎閲嶈繛鍔熻兘
+ */
+ private void reconnect() {
+ if (reconnecting.getAndSet(true)) {
+ logger.debug("閲嶈繛鎿嶄綔宸插湪杩涜涓紝璺宠繃鏈閲嶈繛");
+ return;
+ }
+
+ logger.info("寮�濮嬫柇绾块噸杩�...");
+ while (running) {
+ try {
+ logger.info("灏濊瘯閲嶈繛锛岀洰鏍囨湇鍔″櫒: {}:{}", serverIp, serverPort);
+
+ // 鍏抽棴鏃ц繛鎺�
+ closeResources(reader, inputStream, outputStream, socket);
+
+ // 绛夊緟涓�娈垫椂闂村悗閲嶈繛
+ Thread.sleep(RECONNECT_INTERVAL);
+
+ // 灏濊瘯閲嶆柊杩炴帴
+ if (connect(serverIp, serverPort)) {
+ // 閲嶆柊鐧诲綍
+ if (deviceId != null) {
+ Map<String, Object> loginResponse = sendLoginRequest(deviceId);
+ if (loginResponse != null &&
+ "logined".equals(loginResponse.get("cmd")) &&
+ "100".equals(String.valueOf(loginResponse.get("code")))) {
+
+ logger.info("閲嶈繛骞剁櫥褰曟垚鍔�");
+ reconnecting.set(false);
+
+ // 閲嶆柊鍚姩娑堟伅鐩戝惉
+ if (messageListener != null) {
+ startMessageListener(messageListener);
+ }
+ return;
+ }
+ } else {
+ // 濡傛灉娌℃湁璁惧ID锛屽彧杩炴帴涓嶇櫥褰�
+ logger.info("閲嶈繛鎴愬姛");
+ reconnecting.set(false);
+ if (messageListener != null) {
+ startMessageListener(messageListener);
+ }
+ return;
+ }
+ }
+
+ logger.warn("閲嶈繛澶辫触锛寋} 姣鍚庨噸璇�", RECONNECT_INTERVAL);
+
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ logger.warn("閲嶈繛杩囩▼琚腑鏂�");
+ break;
+ } catch (Exception e) {
+ logger.error("閲嶈繛寮傚父: {}", e.getMessage());
+ }
+ }
+
+ reconnecting.set(false);
+ if (running) {
+ logger.error("閲嶈繛寰幆閫�鍑猴紝灏嗗湪涓嬫鏂紑鍚庨噸鏂板皾璇�");
+ }
+ }
+
+ /**
+ * 鍚姩娑堟伅鐩戝惉鍣�
+ * @param listener 娑堟伅鐩戝惉鍥炶皟鎺ュ彛
+ */
+ public void startMessageListener(MessageListener listener) {
+ this.messageListener = listener;
+ running = true;
+ new Thread(() -> {
+ try {
+ while (running && socket != null && !socket.isClosed()) {
+ try {
+ String message = reader.readLine();
+ if (message != null) {
+ logger.debug("鏀跺埌鏈嶅姟鍣ㄦ秷鎭�: {}", message);
+
+ // 瑙f瀽娑堟伅
+ Map<String, Object> parsedMessage = parseJson(message);
+
+ // 鍥炶皟缁欑洃鍚櫒
+ if (messageListener != null) {
+ messageListener.onMessageReceived(message, parsedMessage);
+ }
+ } else {
+ // 璇诲埌null琛ㄧず杩炴帴宸插叧闂�
+ logger.warn("杩炴帴琚湇鍔″櫒鍏抽棴");
+ break;
+ }
+ } catch (IOException e) {
+ if (running) {
+ logger.error("璇诲彇娑堟伅寮傚父: {}", e.getMessage());
+ // 濡傛灉涓嶆槸涓诲姩鍋滄锛屽皾璇曢噸杩�
+ if (running && !reconnecting.get()) {
+ reconnect();
+ }
+ break;
+ }
+ }
+ }
+ } finally {
+ logger.info("娑堟伅鐩戝惉绾跨▼缁撴潫");
+ // 濡傛灉杩樺湪杩愯鐘舵�佷絾杩炴帴宸叉柇寮�锛屽皾璇曢噸杩�
+ if (running && !reconnecting.get()) {
+ reconnect();
+ }
+ }
+ }, "TCP-Client-Listener").start();
+ }
+
+ /**
+ * 鍋滄娑堟伅鐩戝惉
+ */
+ public void stopMessageListener() {
+ running = false;
+ messageListener = null;
+ reconnecting.set(false); // 鍋滄閲嶈繛
+ }
+
+ /**
+ * 瑙f瀽绠�鍗旿SON瀛楃涓蹭负Map
+ * @param json JSON瀛楃涓�
+ * @return 瑙f瀽鍚庣殑Map
+ */
+ public Map<String, Object> parseJson(String json) {
+ Map<String, Object> result = new HashMap<>();
+ if (json == null || json.trim().isEmpty()) {
+ return result;
+ }
+
+ // 绉婚櫎棣栧熬鐨剓}
+ String content = json.trim();
+ if (content.startsWith("{") && content.endsWith("}")) {
+ content = content.substring(1, content.length() - 1).trim();
+ }
+
+ Matcher matcher = JSON_PATTERN.matcher(content);
+ while (matcher.find()) {
+ String key = matcher.group(1);
+ String value = matcher.group(2).trim();
+
+ // 绉婚櫎鍊肩殑寮曞彿锛堝鏋滃瓨鍦級
+ if (value.startsWith("\"") && value.endsWith("\"")) {
+ value = value.substring(1, value.length() - 1);
+ }
+
+ // 澶勭悊null鍊�
+ if ("null".equals(value)) {
+ result.put(key, null);
+ } else {
+ result.put(key, value);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * 瑙f瀽浜哄憳鏁版嵁鏁扮粍
+ * @param dataStr 鏁版嵁瀛楃涓�
+ * @return 浜哄憳鍒楄〃
+ */
+ private List<Map<String, Object>> parsePersonDataArray(String dataStr) {
+ List<Map<String, Object>> result = new ArrayList<>();
+ if (dataStr == null || dataStr.trim().isEmpty()) {
+ return result;
+ }
+
+ // 浣跨敤姝e垯琛ㄨ揪寮忓尮閰嶆暟缁勪腑鐨勬瘡涓璞�
+ Matcher matcher = ARRAY_PATTERN.matcher(dataStr);
+ while (matcher.find()) {
+ String objStr = matcher.group(1);
+ Map<String, Object> person = parsePersonObject(objStr);
+ if (!person.isEmpty()) {
+ result.add(person);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * 瑙f瀽鍗曚釜浜哄憳瀵硅薄
+ * @param objStr 瀵硅薄瀛楃涓�
+ * @return 浜哄憳淇℃伅Map
+ */
+ private Map<String, Object> parsePersonObject(String objStr) {
+ Map<String, Object> person = new HashMap<>();
+ if (objStr == null || objStr.trim().isEmpty()) {
+ return person;
+ }
+
+ // 鍒嗗壊閿�煎
+ String[] pairs = objStr.split(",");
+ for (String pair : pairs) {
+ String[] keyValue = pair.split(":", 2);
+ if (keyValue.length == 2) {
+ String key = keyValue[0].trim();
+ String value = keyValue[1].trim();
+
+ // 绉婚櫎鍊肩殑寮曞彿锛堝鏋滃瓨鍦級
+ if (value.startsWith("'") && value.endsWith("'")) {
+ value = value.substring(1, value.length() - 1);
+ } else if (value.startsWith("\"") && value.endsWith("\"")) {
+ value = value.substring(1, value.length() - 1);
+ }
+
+ person.put(key, value);
+ }
+ }
+
+ return person;
+ }
+
+ /**
+ * 鏋勫缓鐧诲綍璇锋眰JSON
+ * @return JSON瀛楃涓�
+ */
+ private String buildLoginRequestJson(String deviceId) {
+ return "{\"code\":100,\"cmd\":\"login\",\"deviceId\":\"" + deviceId + "\"}";
+ }
+
+ /**
+ * 鏋勫缓浜哄憳鏁版嵁璇锋眰JSON
+ * @return JSON瀛楃涓�
+ */
+ private String buildBatchGetRequestJson(String deviceId) {
+ return "{\"code\":101,\"cmd\":\"batchGet\",\"deviceId\":\"" + deviceId + "\"}";
+ }
+
+ /**
+ * 鏋勫缓閫氱敤鍛戒护JSON
+ * @param code 鍛戒护浠g爜
+ * @param cmd 鍛戒护绫诲瀷
+ * @param data 鏁版嵁
+ * @return JSON瀛楃涓�
+ */
+ private String buildCommandJson(String code, String cmd, String data) {
+ if (data != null) {
+ return "{\"code\":\"" + code + "\",\"cmd\":\"" + cmd + "\",\"data\":\"" + data + "\"}";
+ } else {
+ return "{\"code\":\"" + code + "\",\"cmd\":\"" + cmd + "\",\"data\":null}";
+ }
+ }
+
+ /**
+ * 鍏抽棴杩炴帴
+ */
+ public void disconnect() {
+ stopMessageListener();
+ closeResources(reader, inputStream, outputStream, socket);
+ logger.info("鏂紑涓庢湇鍔″櫒鐨勮繛鎺�");
+ }
+
+ /**
+ * 妫�鏌ヨ繛鎺ョ姸鎬�
+ * @return 鏄惁杩炴帴
+ */
+ public boolean isConnected() {
+ return socket != null && !socket.isClosed() && socket.isConnected();
+ }
+
+ /**
+ * 鍏抽棴鎵�鏈夎祫婧�
+ */
+ private static void closeResources(Closeable... resources) {
+ for (Closeable resource : resources) {
+ if (resource != null) {
+ try {
+ resource.close();
+ } catch (IOException e) {
+ logger.error("鍏抽棴璧勬簮鏃跺彂鐢熷紓甯�: {}", e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+ /**
+ * 娑堟伅鐩戝惉鍥炶皟鎺ュ彛
+ */
+ public interface MessageListener {
+ /**
+ * 褰撴敹鍒版湇鍔″櫒娑堟伅鏃跺洖璋�
+ * @param rawMessage 鍘熷娑堟伅瀛楃涓�
+ * @param parsedMessage 瑙f瀽鍚庣殑娑堟伅Map
+ */
+ void onMessageReceived(String rawMessage, Map<String, Object> parsedMessage);
+
+ }
+}
\ No newline at end of file
diff --git a/src/jiekou/lunxunkazhuangtai.java b/src/jiekou/lunxunkazhuangtai.java
new file mode 100644
index 0000000..49c8774
--- /dev/null
+++ b/src/jiekou/lunxunkazhuangtai.java
@@ -0,0 +1,174 @@
+package jiekou;
+import chushihua.SlotManager;
+import xitongshezhi.Fkj;
+
+/**
+ * 杞鍗℃Ы鐘舵�佺被
+ * 鐢ㄤ簬瀹氭湡杞骞惰緭鍑烘墍鏈夊崱妲界殑鐘舵�佷俊鎭�
+ */
+public class lunxunkazhuangtai {
+ private static Thread pollThread;
+ private static volatile boolean isRunning = false;
+ private static final int POLL_INTERVAL = 30000; // 30绉掗棿闅�
+
+ /**
+ * 鍚姩杞绾跨▼
+ */
+ public static void startPolling() {
+ if (isRunning) {;
+ return;
+ }
+
+ isRunning = true;
+ pollThread = new Thread(new PollingTask(), "SlotStatusPollingThread");
+ pollThread.setDaemon(true); // 璁剧疆涓哄畧鎶ょ嚎绋嬶紝褰撲富绾跨▼缁撴潫鏃惰嚜鍔ㄧ粨鏉�
+ pollThread.start();
+ }
+
+ /**
+ * 鍋滄杞绾跨▼
+ */
+ public static void stopPolling() {
+ isRunning = false;
+ if (pollThread != null) {
+ pollThread.interrupt();
+ pollThread = null;
+ }
+ System.out.println("鍗℃Ы鐘舵�佽疆璇㈢嚎绋嬪凡鍋滄");
+ }
+
+ /**
+ * 妫�鏌ヨ疆璇㈢嚎绋嬫槸鍚﹀湪杩愯
+ * @return 杩愯鐘舵��
+ */
+ public static boolean isPolling() {
+ return isRunning;
+ }
+
+ /**
+ * 杞浠诲姟瀹炵幇
+ */
+ private static class PollingTask implements Runnable {
+ @Override
+ public void run() {
+ while (isRunning && !Thread.currentThread().isInterrupted()) {
+ try {
+ // 杈撳嚭鎵�鏈夊崱妲界姸鎬�
+ printAllSlotsStatus();
+
+ // 绛夊緟鎸囧畾闂撮殧
+ Thread.sleep(POLL_INTERVAL);
+ } catch (InterruptedException e) {
+ System.out.println("杞绾跨▼琚腑鏂�");
+ Thread.currentThread().interrupt();
+ break;
+ } catch (Exception e) {
+ System.err.println("杞杩囩▼涓彂鐢熼敊璇�: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+ isRunning = false;
+ }
+
+ /**
+ * 杈撳嚭鎵�鏈夊崱妲界姸鎬佷俊鎭�
+ */
+ private void printAllSlotsStatus() {
+ Fkj[] slots = SlotManager.getSlotArray();
+ if (slots == null || slots.length == 0) {
+ return;
+ }
+ for (Fkj slot : slots) {
+ if (slot != null) {
+ //浣跨敤涓嬮潰鐨勬帹缁欐湇鍔″櫒鍗$殑鐘舵��
+ String kacaobianhao=safeGetValue(slot.getSlotNumber());
+ String kahao=safeGetValue(slot.getCardNumber());
+ String shifouyouka=formatHasCard(safeGetValue(slot.getHasCard()));
+ String kazhuangtai=formatWorkStatus(safeGetValue(slot.getWorkStatus()));
+ String kacaodianya=safeGetValue(slot.getVoltage());
+ String kacaodianliu=safeGetValue(slot.getCurrent());
+ String guzhangyuanyin=formatFault(safeGetValue(slot.getFault()));
+ }
+ }
+
+ }
+
+ /**
+ * 瀹夊叏鑾峰彇鍊硷紝閬垮厤绌烘寚閽�
+ */
+ private String safeGetValue(String value) {
+ return value != null ? value : "null";
+ }
+
+ /**
+ * 鏍煎紡鍖栨湁鍗$姸鎬�
+ */
+ private String formatHasCard(String hasCard) {
+ if ("1".equals(hasCard)) return "鏈夊崱";
+ if ("0".equals(hasCard)) return "鏃犲崱";
+ if ("-1".equals(hasCard)) return "鏈煡";
+ return hasCard;
+ }
+
+ /**
+ * 鏍煎紡鍖栧伐浣滅姸鎬�
+ */
+ private String formatWorkStatus(String status) {
+ switch (status) {
+ case "0": return "鏃犳晥";
+ case "1": return "寰呮満";
+ case "2": return "鍏呯數涓�";
+ case "3": return "宸插厖婊�";
+ case "4": return "鏁呴殰";
+ case "5": return "鎺堟潈鍒版湡";
+ case "6": return "閫氫俊瓒呮椂";
+ case "-1": return "鏈煡";
+ default: return status;
+ }
+ }
+
+ /**
+ * 鏍煎紡鍖栨晠闅滅姸鎬�
+ */
+ private String formatFault(String fault) {
+ switch (fault) {
+ case "0": return "姝e父";
+ case "1": return "鎻掑崱閿欒";
+ case "2": return "杩囨祦";
+ case "3": return "闂ㄦ帶鏁呴殰";
+ case "4": return "杩囧帇";
+ case "5": return "娆犲帇";
+ case "-1": return "鏈煡";
+ default: return fault;
+ }
+ }
+ }
+
+ /**
+ * 璁剧疆杞闂撮殧锛堝崟浣嶏細姣锛�
+ * @param interval 闂撮殧鏃堕棿锛屾绉�
+ */
+ public static void setPollInterval(int interval) {
+ // 娉ㄦ剰锛氳繖涓缃笉浼氱珛鍗崇敓鏁堬紝闇�瑕侀噸鍚疆璇㈢嚎绋�
+ System.out.println("鏂扮殑杞闂撮殧灏嗗湪涓嬫鍚姩鏃剁敓鏁�: " + interval + "ms");
+ }
+
+ /**
+ * 鑾峰彇褰撳墠杞闂撮殧
+ * @return 杞闂撮殧锛堟绉掞級
+ */
+ public static int getPollInterval() {
+ return POLL_INTERVAL;
+ }
+
+ /**
+ * 鎵嬪姩瑙﹀彂涓�娆$姸鎬佽緭鍑猴紙涓嶇瓑寰呴棿闅旓級
+ */
+ public static void triggerManualOutput() {
+ if (isRunning) {
+ new PollingTask().printAllSlotsStatus();
+ } else {
+ System.out.println("杞绾跨▼鏈繍琛岋紝鏃犳硶鎵嬪姩瑙﹀彂杈撳嚭");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/publicway/ProtocolParser01.java b/src/publicway/ProtocolParser01.java
index 8a0d0fa..4f0943c 100644
--- a/src/publicway/ProtocolParser01.java
+++ b/src/publicway/ProtocolParser01.java
@@ -1,6 +1,8 @@
package publicway;
import java.util.ArrayList;
import java.util.List;
+
+import chuankou.SerialPortService;
import chushihua.SlotManager;
public class ProtocolParser01 {
@@ -526,7 +528,9 @@
String.format("%.2f", voltage), // 电压
String.format("%.2f", current), // 电流
getFaultsString() // 故障1插卡错误;2过流;3,门控故障;4过压;5欠压;
- );
+ );
+
+
}
}
diff --git a/src/publicway/SerialProtocolParser.java b/src/publicway/SerialProtocolParser.java
index c80bf15..2af77a8 100644
--- a/src/publicway/SerialProtocolParser.java
+++ b/src/publicway/SerialProtocolParser.java
@@ -5,6 +5,7 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
+import chuankou.SerialPortService;
import publicway.ProtocolParser01.ParseResult;
public class SerialProtocolParser {
@@ -273,6 +274,7 @@
*/
private void parsePacket(byte[] packet) {
try {
+ SerialPortService.getReceivedDataCount();
// 瑙f瀽鍩烘湰瀛楁
byte hostAddress = packet[4]; // 涓绘満鍦板潃
byte slotAddress = packet[5]; // 鍗℃Ы鍦板潃
@@ -296,7 +298,7 @@
// 浣跨敤浼樺寲鐨勫瓧鑺傛暟缁勮В鏋愭柟娉曪紝閬垮厤瀛楃涓茶浆鎹�
ParseResult rst = ProtocolParser01.parseDDCC01Data(packet);
rst.fuzhi();
- rst.toString();
+// rst.toString();
}
break;
case FUNCTION_51:
diff --git a/src/xitongshezhi/Charulog.java b/src/xitongshezhi/Charulog.java
new file mode 100644
index 0000000..fd0a9e6
--- /dev/null
+++ b/src/xitongshezhi/Charulog.java
@@ -0,0 +1,148 @@
+package xitongshezhi;
+
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class Charulog {
+ private static final String LOG_FILE = "log.properties";
+ private static final int MAX_RECORDS = 500;
+ private static final ReentrantLock lock = new ReentrantLock();
+ private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ /**
+ * 闈欐�佹柟娉曪細璁板綍鎿嶄綔鏃ュ織
+ * @param operation 鎿嶄綔鍐呭
+ */
+ public static void logOperation(String operation) {
+ lock.lock();
+ try {
+ // 娣诲姞鏃堕棿鎴�
+ String timestamp = dateFormat.format(new Date());
+ String logEntry = "[" + timestamp + "] " + operation;
+
+ // 璇诲彇鐜版湁鏃ュ織
+ Properties logProps = readLogFile();
+
+ // 娣诲姞鏂拌褰�
+ addNewLogEntry(logProps, logEntry);
+
+ // 濡傛灉瓒呰繃鏈�澶ц褰曟暟锛屽垹闄ゆ渶鏃╃殑璁板綍
+ if (logProps.size() > MAX_RECORDS) {
+ removeOldestEntries(logProps);
+ }
+
+ // 鍐欏洖鏂囦欢
+ writeLogFile(logProps);
+
+ } catch (Exception e) {
+ System.err.println("璁板綍鏃ュ織鏃跺彂鐢熼敊璇�: " + e.getMessage());
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * 璇诲彇鏃ュ織鏂囦欢
+ */
+ private static Properties readLogFile() {
+ Properties props = new Properties();
+ File file = new File(LOG_FILE);
+
+ if (file.exists()) {
+ try (FileInputStream fis = new FileInputStream(file)) {
+ props.load(fis);
+ } catch (IOException e) {
+ System.err.println("璇诲彇鏃ュ織鏂囦欢澶辫触: " + e.getMessage());
+ }
+ }
+
+ return props;
+ }
+
+ /**
+ * 娣诲姞鏂扮殑鏃ュ織鏉$洰
+ */
+ private static void addNewLogEntry(Properties props, String logEntry) {
+ // 浣跨敤鏃堕棿鎴充綔涓簁ey锛岀‘淇濆敮涓�鎬�
+ String key = "log_" + System.currentTimeMillis() + "_" + UUID.randomUUID().toString().substring(0, 8);
+ props.setProperty(key, logEntry);
+ }
+
+ /**
+ * 绉婚櫎鏈�鏃╃殑璁板綍
+ */
+ private static void removeOldestEntries(Properties props) {
+ // 灏嗗睘鎬ц浆鎹负鍒楄〃浠ヤ究鎺掑簭
+ List<Map.Entry<Object, Object>> entries = new ArrayList<>(props.entrySet());
+
+ // 鎸夐敭鎺掑簭锛堝亣璁鹃敭鍖呭惈鏃堕棿淇℃伅锛�
+ entries.sort((e1, e2) -> {
+ String key1 = (String) e1.getKey();
+ String key2 = (String) e2.getKey();
+ return key1.compareTo(key2);
+ });
+
+ // 鍒犻櫎瓒呭嚭闄愬埗鐨勬渶鏃╄褰�
+ while (entries.size() > MAX_RECORDS) {
+ Map.Entry<Object, Object> oldest = entries.remove(0);
+ props.remove(oldest.getKey());
+ }
+ }
+
+ /**
+ * 鍐欏叆鏃ュ織鏂囦欢
+ */
+ private static void writeLogFile(Properties props) {
+ try (FileOutputStream fos = new FileOutputStream(LOG_FILE)) {
+ // 娣诲姞鏂囦欢澶存敞閲�
+ props.store(fos, "鎿嶄綔鏃ュ織璁板綍 - 鏈�鍚庢洿鏂�: " + new Date());
+ } catch (IOException e) {
+ System.err.println("鍐欏叆鏃ュ織鏂囦欢澶辫触: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 鑾峰彇褰撳墠鏃ュ織璁板綍鏁伴噺锛堢敤浜庢祴璇曪級
+ */
+ public static int getLogCount() {
+ Properties props = readLogFile();
+ return props.size();
+ }
+
+ /**
+ * 娓呯┖鏃ュ織鏂囦欢锛堢敤浜庢祴璇曪級
+ */
+ public static void clearLogs() {
+ lock.lock();
+ try {
+ Properties props = new Properties();
+ writeLogFile(props);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * 璇诲彇骞舵墦鍗版墍鏈夋棩蹇楋紙鐢ㄤ簬娴嬭瘯锛�
+ */
+ public static void printAllLogs() {
+ Properties props = readLogFile();
+ List<Map.Entry<Object, Object>> entries = new ArrayList<>(props.entrySet());
+
+ // 鎸夐敭鎺掑簭
+ entries.sort((e1, e2) -> {
+ String key1 = (String) e1.getKey();
+ String key2 = (String) e2.getKey();
+ return key1.compareTo(key2);
+ });
+
+ System.out.println("=== 鎿嶄綔鏃ュ織璁板綍 (鍏� " + entries.size() + " 鏉�) ===");
+ for (Map.Entry<Object, Object> entry : entries) {
+ System.out.println(entry.getValue());
+ }
+ System.out.println("=== 鏃ュ織缁撴潫 ===");
+ }
+
+}
\ No newline at end of file
diff --git a/src/xitongshezhi/ConfigSet.java b/src/xitongshezhi/ConfigSet.java
index 135de99..98e5435 100644
--- a/src/xitongshezhi/ConfigSet.java
+++ b/src/xitongshezhi/ConfigSet.java
@@ -3,7 +3,6 @@
import javax.swing.*;
import javax.swing.border.EmptyBorder;
-import chuankou.SystemDebugDialog;
import chushihua.Chushihua;
import chushihua.lunxun;
@@ -345,7 +344,7 @@
kacaoguanli.showSlotManagementDialog((JFrame) getParent());
break;
case "鍘嗗彶璁板綍":
- showMessageDialog("鍘嗗彶璁板綍鍔熻兘寮�鍙戜腑...");
+ lishijilu.showHistoryDialog((JFrame) getParent());
break;
case "鍙傛暟璁剧疆":
canshushezhi.showSettingsDialog((JFrame) getParent());
@@ -357,10 +356,10 @@
mimaguanli.showPasswordManagementDialog((JFrame) getParent(), configManager);
break;
case "鐗堟湰绠$悊":
- showMessageDialog("鐗堟湰绠$悊鍔熻兘寮�鍙戜腑...");
+ banbenguanli.showVersionManagementDialog((JFrame) getParent());
break;
case "璇█璁剧疆":
- showMessageDialog("璇█璁剧疆鍔熻兘寮�鍙戜腑...");
+ showMessageDialog("璇█璁剧疆涓嶅彲閫夋嫨");
break;
}
}
diff --git a/src/xitongshezhi/Dingshidialog.java b/src/xitongshezhi/Dingshidialog.java
new file mode 100644
index 0000000..6a564c2
--- /dev/null
+++ b/src/xitongshezhi/Dingshidialog.java
@@ -0,0 +1,260 @@
+package xitongshezhi;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.Frame;
+import java.io.File;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.border.EmptyBorder;
+
+/**
+ * 瀹氭椂鍏抽棴瀵硅瘽妗�
+ * 浣跨敤闈欐�佹柟娉曢伩鍏嶅唴瀛樻硠婕�
+ */
+public class Dingshidialog {
+
+ /**
+ * 鏄剧ず瀹氭椂鍏抽棴瀵硅瘽妗�
+ * @param parent 鐖剁獥鍙�
+ * @param countdownTime 鍊掕鏃舵椂闂达紙绉掞級
+ * @param message 鎻愮ず淇℃伅
+ * @param audioFile MP3鏂囦欢鍚嶏紙鏍圭洰褰曚笅锛屾棤闇�鎵╁睍鍚嶏級
+ * @return 1-鎴愬姛 0-澶辫触
+ */
+ public static int showTimedDialog(Frame parent, int countdownTime, String message, String audioFile) {
+ TimedDialog dialog = new TimedDialog(parent, countdownTime, message, audioFile);
+ return dialog.showDialog();
+ }
+
+ /**
+ * 鍐呴儴瀵硅瘽妗嗙被锛岀‘淇濅娇鐢ㄥ悗鑳借鍨冨溇鍥炴敹
+ */
+ @SuppressWarnings("serial")
+ private static class TimedDialog extends JDialog {
+ private JLabel countdownLabel;
+ private int remainingTime;
+ private int result = 0;
+ private Clip audioClip;
+ private volatile boolean running = true;
+
+ public TimedDialog(Frame parent, int countdownTime, String message, String audioFile) {
+ super(parent, "", true);
+ this.remainingTime = countdownTime;
+ initializeUI(message);
+ startCountdown();
+ playAudio(audioFile);
+ }
+
+ private void initializeUI(String message) {
+ // 璁剧疆瀵硅瘽妗嗗睘鎬�
+ setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ setResizable(false);
+
+ // 鍒涘缓涓婚潰鏉� - 浣跨敤涓嶉�忔槑鑳屾櫙
+ JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
+ mainPanel.setBackground(new Color(15, 28, 48));
+ mainPanel.setBorder(new EmptyBorder(25, 30, 25, 30));
+ mainPanel.setOpaque(true);
+
+ // 鍒涘缓鏍囬鍖哄煙
+ JLabel titleLabel = new JLabel("");
+ titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 20));
+ titleLabel.setForeground(new Color(52, 152, 219));
+ titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
+ titleLabel.setBorder(new EmptyBorder(0, 0, 15, 0));
+
+ // 鍒涘缓娑堟伅鍖哄煙闈㈡澘
+ JPanel messagePanel = new JPanel(new BorderLayout(10, 10));
+ messagePanel.setBackground(new Color(15, 28, 48));
+ messagePanel.setOpaque(true);
+ messagePanel.setBorder(new EmptyBorder(10, 0, 10, 0));
+
+ // 鍒涘缓娑堟伅鏍囩
+ JLabel messageLabel = new JLabel("<html><div style='text-align: center; width: 300px;'>" + message + "</div></html>");
+ messageLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 20));
+ messageLabel.setForeground(new Color(52, 152, 219));
+ messageLabel.setHorizontalAlignment(SwingConstants.CENTER);
+
+ // 鍒涘缓鍊掕鏃舵爣绛�
+ countdownLabel = new JLabel("鍓╀綑鏃堕棿: " + remainingTime + "绉�");
+ countdownLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 16));
+ countdownLabel.setForeground(new Color(231, 76, 60));
+ countdownLabel.setHorizontalAlignment(SwingConstants.CENTER);
+ countdownLabel.setBorder(new EmptyBorder(15, 0, 0, 0));
+
+ // 缁勮娑堟伅鍖哄煙
+ messagePanel.add(messageLabel, BorderLayout.CENTER);
+ messagePanel.add(countdownLabel, BorderLayout.SOUTH);
+
+ // 鍒涘缓鎸夐挳闈㈡澘
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 0));
+ buttonPanel.setBackground(new Color(15, 28, 48));
+ buttonPanel.setOpaque(true);
+ buttonPanel.setBorder(new EmptyBorder(15, 0, 0, 0));
+
+ // 鍒涘缓绔嬪嵆鍏抽棴鎸夐挳
+ JButton closeButton = createStyledButton("绔嬪嵆鍏抽棴", new Color(231, 76, 60));
+ buttonPanel.add(closeButton);
+
+ // 缁勮涓婚潰鏉�
+ mainPanel.add(titleLabel, BorderLayout.NORTH);
+ mainPanel.add(messagePanel, BorderLayout.CENTER);
+ mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+
+ // 璁剧疆瀵硅瘽妗嗗唴瀹�
+ getContentPane().setBackground(new Color(15, 28, 48));
+ getContentPane().add(mainPanel);
+ pack();
+ setLocationRelativeTo(getParent());
+
+ // 鎸夐挳浜嬩欢澶勭悊
+ closeButton.addActionListener(e -> {
+ result = 1;
+ disposeDialog();
+ });
+
+ // 瀵硅瘽妗嗗叧闂簨浠�
+ addWindowListener(new java.awt.event.WindowAdapter() {
+ @Override
+ public void windowClosing(java.awt.event.WindowEvent e) {
+ disposeDialog();
+ }
+ });
+ }
+
+ /**
+ * 寮�濮嬪�掕鏃�
+ */
+ private void startCountdown() {
+ Thread countdownThread = new Thread(() -> {
+ try {
+ while (running && remainingTime > 0) {
+ Thread.sleep(1000);
+ remainingTime--;
+
+ SwingUtilities.invokeLater(() -> {
+ if (countdownLabel != null) {
+ countdownLabel.setText("鍓╀綑鏃堕棿: " + remainingTime + "绉�");
+ }
+ });
+
+ if (remainingTime <= 0) {
+ SwingUtilities.invokeLater(() -> {
+ result = 1;
+ disposeDialog();
+ });
+ break;
+ }
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ });
+ countdownThread.setDaemon(true);
+ countdownThread.start();
+ }
+
+ /**
+ * 鎾斁闊抽鏂囦欢
+ */
+ private void playAudio(String audioFileName) {
+ if (audioFileName == null || audioFileName.trim().isEmpty()) {
+ return;
+ }
+
+ try {
+ String filePath = audioFileName.endsWith(".mp3") ? audioFileName : audioFileName + ".mp3";
+ File audioFile = new File(filePath);
+
+ if (!audioFile.exists()) {
+ System.err.println("闊抽鏂囦欢涓嶅瓨鍦�: " + audioFile.getAbsolutePath());
+ return;
+ }
+
+ AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(audioFile);
+ audioClip = AudioSystem.getClip();
+ audioClip.open(audioInputStream);
+ audioClip.start();
+
+ } catch (Exception e) {
+ System.err.println("鎾斁闊抽澶辫触: " + e.getMessage());
+ // 瀹為檯椤圭洰涓簲浣跨敤鏀寔MP3鐨勫簱
+ }
+ }
+
+ /**
+ * 鍒涘缓鏍峰紡鍖栨寜閽�
+ */
+ private JButton createStyledButton(String text, Color color) {
+ JButton button = new JButton(text);
+ button.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
+ button.setBackground(color);
+ button.setForeground(Color.WHITE);
+ button.setFocusPainted(false);
+ button.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
+ button.setCursor(new Cursor(Cursor.HAND_CURSOR));
+
+ button.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseEntered(java.awt.event.MouseEvent evt) {
+ button.setBackground(brighterColor(color));
+ }
+
+ public void mouseExited(java.awt.event.MouseEvent evt) {
+ button.setBackground(color);
+ }
+ });
+
+ return button;
+ }
+
+ private Color brighterColor(Color color) {
+ int r = Math.min(255, color.getRed() + 30);
+ int g = Math.min(255, color.getGreen() + 30);
+ int b = Math.min(255, color.getBlue() + 30);
+ return new Color(r, g, b);
+ }
+
+ /**
+ * 娓呯悊璧勬簮
+ */
+ private void disposeDialog() {
+ running = false;
+
+ // 鍋滄闊抽
+ if (audioClip != null) {
+ if (audioClip.isRunning()) {
+ audioClip.stop();
+ }
+ audioClip.close();
+ audioClip = null;
+ }
+
+ // 娓呯悊UI寮曠敤
+ countdownLabel = null;
+
+ dispose();
+ }
+
+ /**
+ * 鏄剧ず瀵硅瘽妗�
+ */
+ public int showDialog() {
+ setVisible(true);
+ return result;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/chuankou/SystemDebugDialog.java b/src/xitongshezhi/SystemDebugDialog.java
similarity index 98%
rename from src/chuankou/SystemDebugDialog.java
rename to src/xitongshezhi/SystemDebugDialog.java
index 901f2b7..0da3321 100644
--- a/src/chuankou/SystemDebugDialog.java
+++ b/src/xitongshezhi/SystemDebugDialog.java
@@ -1,7 +1,11 @@
-package chuankou;
+package xitongshezhi;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
+
+import chuankou.Sendmsg;
+import chuankou.SerialPortService;
+
import java.awt.*;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -102,7 +106,7 @@
// 鍏抽棴鎸夐挳
JButton closeButton = new JButton("鍏抽棴");
- closeButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
+ closeButton.setFont(new Font("瀹嬩綋", Font.PLAIN, 12));
closeButton.setBackground(DANGER_COLOR);
closeButton.setForeground(Color.WHITE);
closeButton.setFocusPainted(false);
@@ -347,10 +351,12 @@
pollingButton.setText("鍚姩鏌ヨ");
pollingButton.setBackground(SECONDARY_COLOR);
onDataReceivedascii("[" + getCurrentTime() + "] stop\n");
+ lunxun.setDEBUG_ENABLED(false);
}
} else {
// 濡傛灉鏈疆璇紝鍒欏惎鍔�
if (lunxun.startPolling()) {
+ lunxun.setDEBUG_ENABLED(true);
pollingButton.setText("鍋滄鏌ヨ");
pollingButton.setBackground(DANGER_COLOR);
onDataReceivedascii("[" + getCurrentTime() + "] strat\n");
diff --git a/src/xitongshezhi/banbenguanli.java b/src/xitongshezhi/banbenguanli.java
index d92bd61..73aa8cd 100644
--- a/src/xitongshezhi/banbenguanli.java
+++ b/src/xitongshezhi/banbenguanli.java
@@ -1,503 +1,832 @@
package xitongshezhi;
import javax.swing.*;
import java.awt.*;
-import java.awt.event.*;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.io.*;
+import java.net.*;
-public class banbenguanli extends JFrame {
- private JPanel mainPanel;
- private JLabel titleLabel;
- private JButton closeButton;
-
- // 鐗堟湰淇℃伅缁勪欢
- private JLabel currentVersionLabel;
- private JLabel versionDateLabel;
- private JLabel statusIconLabel;
- private JLabel statusTitleLabel;
- private JLabel statusMessageLabel;
- private JPanel latestVersionPanel;
- private JLabel latestVersionLabel;
-
- // 鎸夐挳缁勪欢
- private JButton checkUpdateButton;
- private JButton updateButton;
-
- // 杩涘害鏉$粍浠�
- private JProgressBar downloadProgressBar;
- private JLabel progressPercentLabel;
-
- // 鐗堟湰鏁版嵁
- private String currentVersion = "V2.3.5";
- private String currentDate = "2023-10-15";
- private String latestVersion = "V2.4.0";
- private boolean updateAvailable = false;
-
- // 棰滆壊瀹氫箟
- private final Color BACKGROUND_COLOR = new Color(15, 28, 48);
- private final Color CARD_COLOR = new Color(26, 43, 68);
- private final Color PRIMARY_COLOR = new Color(52, 152, 219);
- private final Color SECONDARY_COLOR = new Color(46, 204, 113);
- private final Color WARNING_COLOR = new Color(243, 156, 18);
- private final Color TEXT_COLOR = new Color(224, 224, 224);
- private final Color TEXT_LIGHT_COLOR = new Color(160, 200, 255);
+@SuppressWarnings("serial")
+public class banbenguanli extends JDialog {
+ private JPanel mainPanel;
+ private JButton closeButton;
- public banbenguanli() {
- initializeUI();
- setupEventListeners();
- updateVersionInfo();
- }
+ // 鐗堟湰淇℃伅缁勪欢
+ private JLabel currentVersionLabel;
+ private JLabel versionDateLabel;
+ private JLabel statusTitleLabel;
+ private JLabel statusMessageLabel;
+ private JPanel latestVersionPanel;
+ private JLabel latestVersionLabel;
- private void initializeUI() {
- // 璁剧疆绐楀彛灞炴�� - 7瀵哥珫灞� (480x800)
- setTitle("鐗堟湰绠$悊 - UWB浜哄憳瀹氫綅鍗″彂鍗℃満绠$悊绯荤粺");
- setSize(480, 800);
- setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- setLocationRelativeTo(null);
- setResizable(false);
-
- // 璁剧疆涓嶉�忔槑鑳屾櫙
- getContentPane().setBackground(BACKGROUND_COLOR);
-
- // 涓婚潰鏉�
- mainPanel = new JPanel();
- mainPanel.setLayout(new BorderLayout());
- mainPanel.setBackground(BACKGROUND_COLOR);
- mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
-
- // 鍒涘缓鐗堟湰绠$悊寮圭獥鍐呭
- JPanel versionPanel = createVersionPanel();
- mainPanel.add(versionPanel, BorderLayout.CENTER);
-
- add(mainPanel);
- }
-
- private JPanel createVersionPanel() {
- JPanel panel = new JPanel();
- panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
- panel.setBackground(CARD_COLOR);
- panel.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(PRIMARY_COLOR, 1),
- BorderFactory.createEmptyBorder(25, 25, 25, 25)
- ));
-
- // 椤堕儴娓愬彉鏉�
- JPanel gradientBar = new JPanel();
- gradientBar.setBackground(PRIMARY_COLOR);
- gradientBar.setPreferredSize(new Dimension(400, 5));
- gradientBar.setMaximumSize(new Dimension(400, 5));
- gradientBar.setAlignmentX(Component.CENTER_ALIGNMENT);
-
- // 鏍囬鍖哄煙
- JPanel headerPanel = new JPanel();
- headerPanel.setLayout(new BoxLayout(headerPanel, BoxLayout.Y_AXIS));
- headerPanel.setBackground(CARD_COLOR);
- headerPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
-
- // 鍥炬爣
- JLabel iconLabel = new JLabel("馃搵");
- iconLabel.setFont(new Font("Segoe UI Emoji", Font.PLAIN, 42));
- iconLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
- iconLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 15, 0));
-
- // 鏍囬
- JLabel titleLabel = new JLabel("鐗堟湰绠$悊");
- titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 24));
- titleLabel.setForeground(TEXT_COLOR);
- titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
-
- // 鍓爣棰�
- JLabel subtitleLabel = new JLabel("UWB浜哄憳瀹氫綅鍗″彂鍗℃満绠$悊绯荤粺");
- subtitleLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
- subtitleLabel.setForeground(TEXT_LIGHT_COLOR);
- subtitleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
- subtitleLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 25, 0));
-
- headerPanel.add(iconLabel);
- headerPanel.add(titleLabel);
- headerPanel.add(subtitleLabel);
-
- // 褰撳墠鐗堟湰鍗$墖
- JPanel currentVersionPanel = createCurrentVersionPanel();
-
- // 鏇存柊鐘舵�佸尯鍩�
- JPanel statusPanel = createStatusPanel();
-
- // 涓嬭浇杩涘害
- JPanel progressPanel = createProgressPanel();
-
- // 鎸夐挳鍖哄煙
- JPanel buttonPanel = createButtonPanel();
-
- // 鍏抽棴鎸夐挳
- JButton closeBtn = new JButton("鍏抽棴");
- closeBtn.setFont(new Font("Microsoft YaHei", Font.BOLD, 15));
- closeBtn.setBackground(new Color(255, 255, 255, 20));
- closeBtn.setForeground(TEXT_COLOR);
- closeBtn.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(255, 255, 255, 50), 1),
- BorderFactory.createEmptyBorder(12, 20, 12, 20)
- ));
- closeBtn.setFocusPainted(false);
- closeBtn.setCursor(new Cursor(Cursor.HAND_CURSOR));
- closeBtn.setAlignmentX(Component.CENTER_ALIGNMENT);
- closeBtn.setMaximumSize(new Dimension(400, 45));
-
- closeButton = closeBtn;
-
- // 缁勮鎵�鏈夌粍浠�
- panel.add(gradientBar);
- panel.add(Box.createRigidArea(new Dimension(0, 20)));
- panel.add(headerPanel);
- panel.add(currentVersionPanel);
- panel.add(Box.createRigidArea(new Dimension(0, 20)));
- panel.add(statusPanel);
- panel.add(Box.createRigidArea(new Dimension(0, 15)));
- panel.add(progressPanel);
- panel.add(Box.createRigidArea(new Dimension(0, 20)));
- panel.add(buttonPanel);
- panel.add(Box.createRigidArea(new Dimension(0, 15)));
- panel.add(closeBtn);
-
- return panel;
- }
-
- private JPanel createCurrentVersionPanel() {
- JPanel panel = new JPanel();
- panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
- panel.setBackground(new Color(15, 28, 48, 150));
- panel.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(255, 255, 255, 12), 1),
- BorderFactory.createEmptyBorder(20, 20, 20, 20)
- ));
- panel.setAlignmentX(Component.CENTER_ALIGNMENT);
- panel.setMaximumSize(new Dimension(400, 150));
-
- // 鐗堟湰鍙锋爣绛�
- currentVersionLabel = new JLabel(currentVersion);
- currentVersionLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 22));
- currentVersionLabel.setForeground(Color.WHITE);
- currentVersionLabel.setBackground(PRIMARY_COLOR);
- currentVersionLabel.setOpaque(true);
- currentVersionLabel.setBorder(BorderFactory.createEmptyBorder(10, 25, 10, 25));
- currentVersionLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
-
- // 鐗堟湰鎻忚堪
- JLabel versionDescLabel = new JLabel("褰撳墠鐗堟湰");
- versionDescLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
- versionDescLabel.setForeground(TEXT_LIGHT_COLOR);
- versionDescLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
- versionDescLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 5, 0));
-
- // 鏇存柊鏃ユ湡
- versionDateLabel = new JLabel("鏈�鍚庢洿鏂�: " + currentDate);
- versionDateLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 13));
- versionDateLabel.setForeground(TEXT_LIGHT_COLOR);
- versionDateLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
-
- panel.add(currentVersionLabel);
- panel.add(versionDescLabel);
- panel.add(versionDateLabel);
-
- return panel;
- }
-
- private JPanel createStatusPanel() {
- JPanel panel = new JPanel();
- panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
- panel.setBackground(new Color(15, 28, 48, 150));
- panel.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(255, 255, 255, 12), 1),
- BorderFactory.createEmptyBorder(20, 20, 20, 20)
- ));
- panel.setAlignmentX(Component.CENTER_ALIGNMENT);
- panel.setMaximumSize(new Dimension(400, 200));
-
- JPanel contentPanel = new JPanel();
- contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
- contentPanel.setBackground(new Color(15, 28, 48, 0));
- contentPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
-
- // 鐘舵�佸浘鏍�
- statusIconLabel = new JLabel("鉁�");
- statusIconLabel.setFont(new Font("Segoe UI Emoji", Font.PLAIN, 48));
- statusIconLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
- statusIconLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
-
- // 鐘舵�佹爣棰�
- statusTitleLabel = new JLabel("绯荤粺宸叉槸鏈�鏂扮増鏈�");
- statusTitleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
- statusTitleLabel.setForeground(TEXT_COLOR);
- statusTitleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
-
- // 鐘舵�佹秷鎭�
- statusMessageLabel = new JLabel("鎮ㄧ殑绯荤粺杩愯鐨勬槸鏈�鏂扮ǔ瀹氱増鏈紝鎵�鏈夊姛鑳芥甯歌繍琛屻��");
- statusMessageLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 13));
- statusMessageLabel.setForeground(TEXT_LIGHT_COLOR);
- statusMessageLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
- statusMessageLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 15, 0));
-
- // 鏈�鏂扮増鏈俊鎭潰鏉�
- latestVersionPanel = new JPanel();
- latestVersionPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
- latestVersionPanel.setBackground(new Color(243, 156, 18, 38));
- latestVersionPanel.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(243, 156, 18, 75), 1),
- BorderFactory.createEmptyBorder(10, 15, 10, 15)
- ));
- latestVersionPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
- latestVersionPanel.setMaximumSize(new Dimension(350, 50));
-
- JLabel arrowLabel = new JLabel("猬嗭笍");
- arrowLabel.setFont(new Font("Segoe UI Emoji", Font.PLAIN, 14));
-
- JLabel latestTextLabel = new JLabel("鏈�鏂扮増鏈�: ");
- latestTextLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
- latestTextLabel.setForeground(WARNING_COLOR);
-
- latestVersionLabel = new JLabel(latestVersion);
- latestVersionLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 15));
- latestVersionLabel.setForeground(WARNING_COLOR);
-
- latestVersionPanel.add(arrowLabel);
- latestVersionPanel.add(latestTextLabel);
- latestVersionPanel.add(latestVersionLabel);
- latestVersionPanel.setVisible(false);
-
- contentPanel.add(statusIconLabel);
- contentPanel.add(statusTitleLabel);
- contentPanel.add(statusMessageLabel);
- contentPanel.add(latestVersionPanel);
-
- panel.add(contentPanel);
-
- return panel;
- }
-
- private JPanel createProgressPanel() {
- JPanel panel = new JPanel();
- panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
- panel.setBackground(CARD_COLOR);
- panel.setAlignmentX(Component.CENTER_ALIGNMENT);
- panel.setMaximumSize(new Dimension(400, 60));
- panel.setVisible(false);
-
- // 杩涘害淇℃伅
- JPanel infoPanel = new JPanel(new BorderLayout());
- infoPanel.setBackground(CARD_COLOR);
- infoPanel.setMaximumSize(new Dimension(400, 25));
-
- JLabel downloadingLabel = new JLabel("涓嬭浇鏇存柊...");
- downloadingLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 13));
- downloadingLabel.setForeground(TEXT_LIGHT_COLOR);
-
- progressPercentLabel = new JLabel("0%");
- progressPercentLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 13));
- progressPercentLabel.setForeground(TEXT_LIGHT_COLOR);
-
- infoPanel.add(downloadingLabel, BorderLayout.WEST);
- infoPanel.add(progressPercentLabel, BorderLayout.EAST);
-
- // 杩涘害鏉�
- downloadProgressBar = new JProgressBar(0, 100);
- downloadProgressBar.setValue(0);
- downloadProgressBar.setBackground(new Color(255, 255, 255, 25));
- downloadProgressBar.setForeground(SECONDARY_COLOR);
- downloadProgressBar.setBorder(BorderFactory.createEmptyBorder());
- downloadProgressBar.setMaximumSize(new Dimension(400, 8));
-
- panel.add(infoPanel);
- panel.add(Box.createRigidArea(new Dimension(0, 8)));
- panel.add(downloadProgressBar);
-
- return panel;
- }
-
- private JPanel createButtonPanel() {
- JPanel panel = new JPanel();
- panel.setLayout(new GridLayout(1, 2, 15, 0));
- panel.setBackground(CARD_COLOR);
- panel.setAlignmentX(Component.CENTER_ALIGNMENT);
- panel.setMaximumSize(new Dimension(400, 50));
-
- // 妫�鏌ユ洿鏂版寜閽�
- checkUpdateButton = new JButton("妫�鏌ユ洿鏂�");
- checkUpdateButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
- checkUpdateButton.setBackground(PRIMARY_COLOR);
- checkUpdateButton.setForeground(Color.WHITE);
- checkUpdateButton.setBorder(BorderFactory.createEmptyBorder(12, 0, 12, 0));
- checkUpdateButton.setFocusPainted(false);
- checkUpdateButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
-
- // 绔嬪嵆鏇存柊鎸夐挳
- updateButton = new JButton("绔嬪嵆鏇存柊");
- updateButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
- updateButton.setBackground(new Color(128, 128, 128));
- updateButton.setForeground(Color.WHITE);
- updateButton.setBorder(BorderFactory.createEmptyBorder(12, 0, 12, 0));
- updateButton.setFocusPainted(false);
- updateButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
- updateButton.setEnabled(false);
-
- panel.add(checkUpdateButton);
- panel.add(updateButton);
-
- return panel;
- }
-
- private void setupEventListeners() {
- // 鍏抽棴鎸夐挳
- closeButton.addActionListener(e -> {
- dispose();
- });
-
- // 妫�鏌ユ洿鏂版寜閽�
- checkUpdateButton.addActionListener(e -> {
- checkForUpdates();
- });
-
- // 绔嬪嵆鏇存柊鎸夐挳
- updateButton.addActionListener(e -> {
- startUpdate();
- });
- }
-
- private void updateVersionInfo() {
- currentVersionLabel.setText(currentVersion);
- versionDateLabel.setText("鏈�鍚庢洿鏂�: " + currentDate);
- latestVersionLabel.setText(latestVersion);
-
- if (updateAvailable) {
- showUpdateAvailable();
- } else {
- showUpToDate();
- }
- }
-
- private void showUpToDate() {
- statusIconLabel.setText("鉁�");
- statusTitleLabel.setText("绯荤粺宸叉槸鏈�鏂扮増鏈�");
- statusMessageLabel.setText("鎮ㄧ殑绯荤粺杩愯鐨勬槸鏈�鏂扮ǔ瀹氱増鏈紝鎵�鏈夊姛鑳芥甯歌繍琛屻��");
- latestVersionPanel.setVisible(false);
- updateButton.setEnabled(false);
- updateButton.setBackground(new Color(128, 128, 128));
- }
-
- private void showUpdateAvailable() {
- statusIconLabel.setText("鈿狅笍");
- statusTitleLabel.setText("鍙戠幇鏂扮増鏈�");
- statusMessageLabel.setText("鏈夋柊鐗堟湰鍙敤锛屽缓璁洿鏂颁互鑾峰緱鏇村ソ鐨勪綋楠屽拰鍔熻兘銆�");
- latestVersionPanel.setVisible(true);
- updateButton.setEnabled(true);
- updateButton.setBackground(SECONDARY_COLOR);
- }
-
- private void checkForUpdates() {
- // 淇濆瓨鍘熷鎸夐挳鐘舵��
- String originalText = checkUpdateButton.getText();
-
- // 鏄剧ず妫�鏌ヤ腑鐘舵��
- checkUpdateButton.setText("妫�鏌ヤ腑...");
- checkUpdateButton.setEnabled(false);
-
- // 妯℃嫙缃戠粶璇锋眰寤惰繜
- Timer timer = new Timer(2000, e -> {
- // 闅忔満鍐冲畾鏄惁鏈夋洿鏂�
- updateAvailable = Math.random() > 0.5;
-
- if (updateAvailable) {
- showUpdateAvailable();
- } else {
- showUpToDate();
- }
-
- // 鎭㈠鎸夐挳鐘舵��
- checkUpdateButton.setText(originalText);
- checkUpdateButton.setEnabled(true);
-
- // 鏄剧ず妫�鏌ュ畬鎴愭彁绀�
- String originalMessage = statusMessageLabel.getText();
- statusMessageLabel.setText(updateAvailable ?
- "鉁� 妫�鏌ュ畬鎴愶紝鍙戠幇鏂扮増鏈彲鐢�" :
- "鉁� 妫�鏌ュ畬鎴愶紝绯荤粺宸叉槸鏈�鏂扮増鏈�");
-
- // 3绉掑悗鎭㈠鍘熸秷鎭�
- Timer restoreTimer = new Timer(3000, e2 -> {
- if (updateAvailable) {
- statusMessageLabel.setText("鏈夋柊鐗堟湰鍙敤锛屽缓璁洿鏂颁互鑾峰緱鏇村ソ鐨勪綋楠屽拰鍔熻兘銆�");
- } else {
- statusMessageLabel.setText("鎮ㄧ殑绯荤粺杩愯鐨勬槸鏈�鏂扮ǔ瀹氱増鏈紝鎵�鏈夊姛鑳芥甯歌繍琛屻��");
- }
- });
- restoreTimer.setRepeats(false);
- restoreTimer.start();
- });
- timer.setRepeats(false);
- timer.start();
- }
-
- private void startUpdate() {
- // 绂佺敤鎸夐挳
- checkUpdateButton.setEnabled(false);
- updateButton.setEnabled(false);
- updateButton.setText("鏇存柊涓�...");
-
- // 鏄剧ず涓嬭浇杩涘害
- JPanel progressPanel = (JPanel) mainPanel.getComponent(0).getComponentAt(275, 500);
- progressPanel.setVisible(true);
-
- // 妯℃嫙涓嬭浇杩涘害
- Timer progressTimer = new Timer(100, null);
- progressTimer.addActionListener(new ActionListener() {
- int progress = 0;
-
- @Override
- public void actionPerformed(ActionEvent e) {
- progress += (int) (Math.random() * 8);
- if (progress >= 100) {
- progress = 100;
- progressTimer.stop();
-
- // 鏇存柊瀹屾垚
- Timer completionTimer = new Timer(500, e2 -> {
- progressPanel.setVisible(false);
- updateButton.setText("鏇存柊瀹屾垚");
- updateButton.setBackground(new Color(149, 165, 166));
-
- // 鏇存柊鐗堟湰淇℃伅
- currentVersion = latestVersion;
- currentDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
- updateAvailable = false;
- updateVersionInfo();
-
- // 鏄剧ず鎴愬姛娑堟伅
- statusIconLabel.setText("鉁�");
- statusTitleLabel.setText("鏇存柊瀹屾垚");
- statusMessageLabel.setText("绯荤粺宸叉垚鍔熸洿鏂板埌鏈�鏂扮増鏈紝鎵�鏈夊姛鑳藉凡浼樺寲銆�");
- });
- completionTimer.setRepeats(false);
- completionTimer.start();
- }
-
- downloadProgressBar.setValue(progress);
- progressPercentLabel.setText(progress + "%");
- }
- });
- progressTimer.start();
- }
-
- // 涓绘柟娉曟祴璇�
- public static void main(String[] args) {
- // 璁剧疆绯荤粺澶栬
- try {
- UIManager.setLookAndFeel(UIManager.getLookAndFeel());
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- SwingUtilities.invokeLater(() -> {
- banbenguanli frame = new banbenguanli();
- frame.setVisible(true);
- });
- }
+ // 鎸夐挳缁勪欢
+ private JButton checkUpdateButton;
+ private JButton updateButton;
+
+ // 杩涘害鏉$粍浠�
+ private JProgressBar downloadProgressBar;
+ private JLabel progressPercentLabel;
+
+ // 鐗堟湰鏁版嵁
+ private String currentVersion = "V1.0.0";
+ private String currentDate = "2025-11-20";
+ private String latestVersion = "V1.0.1";
+ private boolean updateAvailable = false;
+
+ // API閰嶇疆
+ private final String UPDATE_CHECK_URL = "http://39.106.210.13:8090/api/wx/findTbUpapp";
+ private final String LOGIN_URL = "http://39.106.210.13:8090/api/wx/login";
+ private final String APP_NAME = "鍙戝崱app";
+ private final String LOGIN_USERNAME = "鐜嬮";
+ private final String LOGIN_PASSWORD = "admin";
+
+ private String downloadUrl = "";
+ private String releaseNotes = "";
+ private String loginToken = "";
+
+ // 棰滆壊瀹氫箟
+ private final Color BACKGROUND_COLOR = new Color(15, 28, 48);
+ private final Color CARD_COLOR = new Color(26, 43, 68);
+ private final Color PRIMARY_COLOR = new Color(52, 152, 219);
+ private final Color SECONDARY_COLOR = new Color(46, 204, 113);
+ private final Color WARNING_COLOR = new Color(243, 156, 18);
+ private final Color TEXT_COLOR = new Color(224, 224, 224);
+ private final Color TEXT_LIGHT_COLOR = new Color(160, 200, 255);
+
+ public banbenguanli(JFrame parent) {
+ super(parent, "鐗堟湰绠$悊", true);
+ initializeUI();
+ setupEventListeners();
+ updateVersionInfo();
+ }
+
+ private void initializeUI() {
+ // 璁剧疆寮圭獥灞炴�� - 7瀵哥珫灞� (480x800)
+ setTitle("鐗堟湰绠$悊");
+ setSize(480, 800);
+ setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ setLocationRelativeTo(getParent());
+ setResizable(false);
+
+ // 璁剧疆涓嶉�忔槑鑳屾櫙
+ getContentPane().setBackground(BACKGROUND_COLOR);
+
+ // 涓婚潰鏉�
+ mainPanel = new JPanel();
+ mainPanel.setLayout(new BorderLayout());
+ mainPanel.setBackground(BACKGROUND_COLOR);
+ mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+
+ // 鍒涘缓鐗堟湰绠$悊寮圭獥鍐呭
+ JPanel versionPanel = createVersionPanel();
+ mainPanel.add(versionPanel, BorderLayout.CENTER);
+
+ add(mainPanel);
+ }
+
+ private JPanel createVersionPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+ panel.setBackground(CARD_COLOR);
+ panel.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createLineBorder(PRIMARY_COLOR, 1),
+ BorderFactory.createEmptyBorder(25, 25, 25, 25)
+ ));
+
+ // 椤堕儴娓愬彉鏉�
+ JPanel gradientBar = new JPanel();
+ gradientBar.setBackground(PRIMARY_COLOR);
+ gradientBar.setPreferredSize(new Dimension(400, 5));
+ gradientBar.setMaximumSize(new Dimension(400, 5));
+ gradientBar.setAlignmentX(Component.CENTER_ALIGNMENT);
+
+ // 鏍囬鍖哄煙
+ JPanel headerPanel = new JPanel();
+ headerPanel.setLayout(new BoxLayout(headerPanel, BoxLayout.Y_AXIS));
+ headerPanel.setBackground(CARD_COLOR);
+ headerPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
+
+ // 鏍囬
+ JLabel titleLabel = new JLabel("鐗堟湰绠$悊");
+ titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 24));
+ titleLabel.setForeground(TEXT_COLOR);
+ titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
+
+ // 鍓爣棰�
+ JLabel subtitleLabel = new JLabel("UWB浜哄憳瀹氫綅鍗″彂鍗℃満绠$悊绯荤粺");
+ subtitleLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
+ subtitleLabel.setForeground(TEXT_LIGHT_COLOR);
+ subtitleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
+ subtitleLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 25, 0));
+
+ headerPanel.add(titleLabel);
+ headerPanel.add(subtitleLabel);
+
+ // 褰撳墠鐗堟湰鍗$墖
+ JPanel currentVersionPanel = createCurrentVersionPanel();
+
+ // 鏇存柊鐘舵�佸尯鍩�
+ JPanel statusPanel = createStatusPanel();
+
+ // 涓嬭浇杩涘害
+ JPanel progressPanel = createProgressPanel();
+
+ // 鎸夐挳鍖哄煙
+ JPanel buttonPanel = createButtonPanel();
+
+ // 鍏抽棴鎸夐挳
+ JButton closeBtn = new JButton("鍏抽棴");
+ closeBtn.setFont(new Font("Microsoft YaHei", Font.BOLD, 15));
+ closeBtn.setBackground(new Color(60, 60, 60));
+ closeBtn.setForeground(TEXT_COLOR);
+ closeBtn.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createLineBorder(new Color(100, 100, 100), 1),
+ BorderFactory.createEmptyBorder(12, 20, 12, 20)
+ ));
+ closeBtn.setFocusPainted(false);
+ closeBtn.setCursor(new Cursor(Cursor.HAND_CURSOR));
+ closeBtn.setAlignmentX(Component.CENTER_ALIGNMENT);
+ closeBtn.setMaximumSize(new Dimension(400, 45));
+ closeBtn.setOpaque(true);
+
+ closeButton = closeBtn;
+
+ // 缁勮鎵�鏈夌粍浠�
+ panel.add(gradientBar);
+ panel.add(Box.createRigidArea(new Dimension(0, 20)));
+ panel.add(headerPanel);
+ panel.add(currentVersionPanel);
+ panel.add(Box.createRigidArea(new Dimension(0, 20)));
+ panel.add(statusPanel);
+ panel.add(Box.createRigidArea(new Dimension(0, 15)));
+ panel.add(progressPanel);
+ panel.add(Box.createRigidArea(new Dimension(0, 20)));
+ panel.add(buttonPanel);
+ panel.add(Box.createRigidArea(new Dimension(0, 15)));
+ panel.add(closeBtn);
+
+ return panel;
+ }
+
+ private JPanel createCurrentVersionPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+ panel.setBackground(new Color(20, 35, 55));
+ panel.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createLineBorder(new Color(80, 80, 80), 1),
+ BorderFactory.createEmptyBorder(20, 20, 20, 20)
+ ));
+ panel.setAlignmentX(Component.CENTER_ALIGNMENT);
+ panel.setMaximumSize(new Dimension(400, 150));
+ panel.setOpaque(true);
+
+ // 鐗堟湰鍙锋爣绛�
+ currentVersionLabel = new JLabel(currentVersion);
+ currentVersionLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 22));
+ currentVersionLabel.setForeground(Color.WHITE);
+ currentVersionLabel.setBackground(PRIMARY_COLOR);
+ currentVersionLabel.setOpaque(true);
+ currentVersionLabel.setBorder(BorderFactory.createEmptyBorder(10, 25, 10, 25));
+ currentVersionLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
+
+ // 鐗堟湰鎻忚堪
+ JLabel versionDescLabel = new JLabel("褰撳墠鐗堟湰");
+ versionDescLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
+ versionDescLabel.setForeground(TEXT_LIGHT_COLOR);
+ versionDescLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
+ versionDescLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 5, 0));
+ versionDescLabel.setOpaque(true);
+ versionDescLabel.setBackground(new Color(20, 35, 55));
+
+ // 鏇存柊鏃ユ湡
+ versionDateLabel = new JLabel("鏈�鍚庢洿鏂�: " + currentDate);
+ versionDateLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 13));
+ versionDateLabel.setForeground(TEXT_LIGHT_COLOR);
+ versionDateLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
+ versionDateLabel.setOpaque(true);
+ versionDateLabel.setBackground(new Color(20, 35, 55));
+
+ panel.add(currentVersionLabel);
+ panel.add(versionDescLabel);
+ panel.add(versionDateLabel);
+
+ return panel;
+ }
+
+ private JPanel createStatusPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+ panel.setBackground(new Color(20, 35, 55));
+ panel.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createLineBorder(new Color(80, 80, 80), 1),
+ BorderFactory.createEmptyBorder(20, 20, 20, 20)
+ ));
+ panel.setAlignmentX(Component.CENTER_ALIGNMENT);
+ panel.setMaximumSize(new Dimension(400, 150));
+ panel.setOpaque(true);
+
+ JPanel contentPanel = new JPanel();
+ contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
+ contentPanel.setBackground(new Color(20, 35, 55));
+ contentPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
+ contentPanel.setOpaque(true);
+
+ // 鐘舵�佹爣棰�
+ statusTitleLabel = new JLabel("绯荤粺宸叉槸鏈�鏂扮増鏈�");
+ statusTitleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
+ statusTitleLabel.setForeground(TEXT_COLOR);
+ statusTitleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
+ statusTitleLabel.setOpaque(true);
+ statusTitleLabel.setBackground(new Color(20, 35, 55));
+
+ // 鐘舵�佹秷鎭�
+ statusMessageLabel = new JLabel("鎮ㄧ殑绯荤粺杩愯鐨勬槸鏈�鏂扮ǔ瀹氱増鏈紝鎵�鏈夊姛鑳芥甯歌繍琛屻��");
+ statusMessageLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 13));
+ statusMessageLabel.setForeground(TEXT_LIGHT_COLOR);
+ statusMessageLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
+ statusMessageLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 15, 0));
+ statusMessageLabel.setOpaque(true);
+ statusMessageLabel.setBackground(new Color(20, 35, 55));
+
+ // 鏈�鏂扮増鏈俊鎭潰鏉�
+ latestVersionPanel = new JPanel();
+ latestVersionPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
+ latestVersionPanel.setBackground(new Color(60, 50, 30));
+ latestVersionPanel.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createLineBorder(WARNING_COLOR, 1),
+ BorderFactory.createEmptyBorder(10, 15, 10, 15)
+ ));
+ latestVersionPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
+ latestVersionPanel.setMaximumSize(new Dimension(350, 40));
+ latestVersionPanel.setOpaque(true);
+
+ JLabel latestTextLabel = new JLabel("鏈�鏂扮増鏈�: ");
+ latestTextLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
+ latestTextLabel.setForeground(WARNING_COLOR);
+ latestTextLabel.setOpaque(true);
+ latestTextLabel.setBackground(new Color(60, 50, 30));
+
+ latestVersionLabel = new JLabel(latestVersion);
+ latestVersionLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 15));
+ latestVersionLabel.setForeground(WARNING_COLOR);
+ latestVersionLabel.setOpaque(true);
+ latestVersionLabel.setBackground(new Color(60, 50, 30));
+
+ latestVersionPanel.add(latestTextLabel);
+ latestVersionPanel.add(latestVersionLabel);
+ latestVersionPanel.setVisible(false);
+
+ contentPanel.add(statusTitleLabel);
+ contentPanel.add(statusMessageLabel);
+ contentPanel.add(latestVersionPanel);
+
+ panel.add(contentPanel);
+
+ return panel;
+ }
+
+ private JPanel createProgressPanel() {
+ // 灏嗗垱寤虹殑闈㈡澘璧嬪�肩粰鎴愬憳鍙橀噺 progressPanel
+ progressPanel = new JPanel();
+ progressPanel.setLayout(new BoxLayout(progressPanel, BoxLayout.Y_AXIS));
+ progressPanel.setBackground(CARD_COLOR);
+ progressPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
+ progressPanel.setMaximumSize(new Dimension(400, 60));
+ progressPanel.setVisible(false);
+ progressPanel.setOpaque(true);
+
+ // 杩涘害淇℃伅
+ JPanel infoPanel = new JPanel(new BorderLayout());
+ infoPanel.setBackground(CARD_COLOR);
+ infoPanel.setMaximumSize(new Dimension(400, 25));
+ infoPanel.setOpaque(true);
+
+ JLabel downloadingLabel = new JLabel("涓嬭浇鏇存柊...");
+ downloadingLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 13));
+ downloadingLabel.setForeground(TEXT_LIGHT_COLOR);
+ downloadingLabel.setOpaque(true);
+ downloadingLabel.setBackground(CARD_COLOR);
+
+ progressPercentLabel = new JLabel("0%");
+ progressPercentLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 13));
+ progressPercentLabel.setForeground(TEXT_LIGHT_COLOR);
+ progressPercentLabel.setOpaque(true);
+ progressPercentLabel.setBackground(CARD_COLOR);
+
+ infoPanel.add(downloadingLabel, BorderLayout.WEST);
+ infoPanel.add(progressPercentLabel, BorderLayout.EAST);
+
+ // 杩涘害鏉� - 涓嶉�忔槑
+ downloadProgressBar = new JProgressBar(0, 100);
+ downloadProgressBar.setValue(0);
+ downloadProgressBar.setBackground(Color.WHITE);
+ downloadProgressBar.setForeground(SECONDARY_COLOR);
+ downloadProgressBar.setBorder(BorderFactory.createLineBorder(new Color(200, 200, 200)));
+ downloadProgressBar.setMaximumSize(new Dimension(400, 12));
+ downloadProgressBar.setOpaque(true);
+
+ progressPanel.add(infoPanel);
+ progressPanel.add(Box.createRigidArea(new Dimension(0, 8)));
+ progressPanel.add(downloadProgressBar);
+
+ return progressPanel;
+ }
+
+ private JPanel createButtonPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new GridLayout(1, 2, 15, 0));
+ panel.setBackground(CARD_COLOR);
+ panel.setAlignmentX(Component.CENTER_ALIGNMENT);
+ panel.setMaximumSize(new Dimension(400, 50));
+ panel.setOpaque(true);
+
+ // 妫�鏌ユ洿鏂版寜閽�
+ checkUpdateButton = new JButton("妫�鏌ユ洿鏂�");
+ checkUpdateButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
+ checkUpdateButton.setBackground(PRIMARY_COLOR);
+ checkUpdateButton.setForeground(Color.WHITE);
+ checkUpdateButton.setBorder(BorderFactory.createEmptyBorder(12, 0, 12, 0));
+ checkUpdateButton.setFocusPainted(false);
+ checkUpdateButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
+ checkUpdateButton.setOpaque(true);
+
+ // 绔嬪嵆鏇存柊鎸夐挳
+ updateButton = new JButton("绔嬪嵆鏇存柊");
+ updateButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
+ updateButton.setBackground(new Color(128, 128, 128));
+ updateButton.setForeground(Color.WHITE);
+ updateButton.setBorder(BorderFactory.createEmptyBorder(12, 0, 12, 0));
+ updateButton.setFocusPainted(false);
+ updateButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
+ updateButton.setEnabled(false);
+ updateButton.setOpaque(true);
+
+ panel.add(checkUpdateButton);
+ panel.add(updateButton);
+
+ return panel;
+ }
+
+ private void setupEventListeners() {
+ // 鍏抽棴鎸夐挳
+ closeButton.addActionListener(e -> {
+ dispose();
+ });
+
+ // 妫�鏌ユ洿鏂版寜閽�
+ checkUpdateButton.addActionListener(e -> {
+ checkForUpdates();
+ });
+
+ // 绔嬪嵆鏇存柊鎸夐挳
+ updateButton.addActionListener(e -> {
+ startUpdate();
+ });
+ }
+
+ private void updateVersionInfo() {
+ currentVersionLabel.setText(currentVersion);
+ versionDateLabel.setText("鏈�鍚庢洿鏂�: " + currentDate);
+ latestVersionLabel.setText(latestVersion);
+
+ if (updateAvailable) {
+ showUpdateAvailable();
+ } else {
+ showUpToDate();
+ }
+ }
+
+ private void showUpToDate() {
+ statusTitleLabel.setText("绯荤粺宸叉槸鏈�鏂扮増鏈�");
+ statusMessageLabel.setText("鎮ㄧ殑绯荤粺杩愯鐨勬槸鏈�鏂扮ǔ瀹氱増鏈紝鎵�鏈夊姛鑳芥甯歌繍琛屻��");
+ latestVersionPanel.setVisible(false);
+ updateButton.setEnabled(false);
+ updateButton.setBackground(new Color(128, 128, 128));
+ }
+
+ private void showUpdateAvailable() {
+ statusTitleLabel.setText("鍙戠幇鏂扮増鏈�");
+ statusMessageLabel.setText("鏈夋柊鐗堟湰鍙敤锛屽缓璁洿鏂颁互鑾峰緱鏇村ソ鐨勪綋楠屽拰鍔熻兘銆�");
+ latestVersionPanel.setVisible(true);
+ updateButton.setEnabled(true);
+ updateButton.setBackground(SECONDARY_COLOR);
+ }
+
+ // 绠�鍗曠殑 JSON 瑙f瀽鏂规硶
+ private String extractJsonValue(String json, String key) {
+ try {
+ String searchKey = "\"" + key + "\":";
+ int startIndex = json.indexOf(searchKey);
+ if (startIndex == -1) return "";
+
+ startIndex += searchKey.length();
+ int endIndex = json.indexOf(",", startIndex);
+ if (endIndex == -1) endIndex = json.indexOf("}", startIndex);
+ if (endIndex == -1) return "";
+
+ String value = json.substring(startIndex, endIndex).trim();
+ // 鍘婚櫎寮曞彿
+ if (value.startsWith("\"") && value.endsWith("\"")) {
+ value = value.substring(1, value.length() - 1);
+ }
+ return value;
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ private int extractJsonInt(String json, String key) {
+ try {
+ String value = extractJsonValue(json, key);
+ return Integer.parseInt(value);
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ private String normalizeVersion(String version) {
+ if (version == null || version.trim().isEmpty()) return "";
+ String normalized = version.trim();
+ if (!normalized.toUpperCase().startsWith("V")) {
+ normalized = "V" + normalized;
+ }
+ return normalized.replace("v", "V");
+ }
+
+ private void checkForUpdates() {
+ // 淇濆瓨鍘熷鎸夐挳鐘舵��
+ String originalText = checkUpdateButton.getText();
+
+ // 鏄剧ず妫�鏌ヤ腑鐘舵��
+ checkUpdateButton.setText("妫�鏌ヤ腑...");
+ checkUpdateButton.setEnabled(false);
+ statusTitleLabel.setText("妫�鏌ユ洿鏂�");
+ statusMessageLabel.setText("姝e湪妫�鏌ユ渶鏂扮増鏈紝璇风◢鍊�...");
+
+ // 浣跨敤SwingWorker鎵ц缃戠粶璇锋眰锛岄伩鍏嶉樆濉濽I
+ SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
+ @Override
+ protected Boolean doInBackground() throws Exception {
+ try {
+ // 鏋勫缓璇锋眰URL
+ String urlStr = UPDATE_CHECK_URL + "?name=" + URLEncoder.encode(APP_NAME, "UTF-8");
+ URL url = new URL(urlStr);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+ connection.setConnectTimeout(10000);
+ connection.setReadTimeout(15000);
+
+ int responseCode = connection.getResponseCode();
+ if (responseCode == 200) {
+ BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ String inputLine;
+ StringBuilder response = new StringBuilder();
+
+ while ((inputLine = in.readLine()) != null) {
+ response.append(inputLine);
+ }
+ in.close();
+
+ // 瑙f瀽JSON鍝嶅簲锛堜娇鐢ㄧ畝鍗曞瓧绗︿覆澶勭悊锛�
+ String jsonResponse = response.toString();
+ int code = extractJsonInt(jsonResponse, "code");
+
+ if (code == 0) {
+ // 鎻愬彇data瀵硅薄
+ int dataStart = jsonResponse.indexOf("\"data\":");
+ if (dataStart == -1) {
+ throw new Exception("鍝嶅簲涓湭鎵惧埌data瀛楁");
+ }
+
+ String serverVersionRaw = extractJsonValue(jsonResponse, "version");
+ String serverVersion = normalizeVersion(serverVersionRaw);
+ String currentVersionNormalized = normalizeVersion(currentVersion);
+
+ // 姣旇緝鐗堟湰
+ boolean hasUpdate = !serverVersion.equals(currentVersionNormalized);
+
+ if (hasUpdate) {
+ latestVersion = serverVersion;
+ downloadUrl = extractJsonValue(jsonResponse, "address");
+ releaseNotes = extractJsonValue(jsonResponse, "info");
+ if (releaseNotes.isEmpty()) {
+ releaseNotes = "鏈夋柊鐗堟湰鍙敤锛屽缓璁洿鏂颁互鑾峰緱鏇村ソ鐨勪綋楠屽拰鍔熻兘銆�";
+ }
+
+ String uptime = extractJsonValue(jsonResponse, "uptime");
+ if (!uptime.isEmpty()) {
+ currentDate = uptime;
+ }
+ }
+
+ return hasUpdate;
+ } else {
+ throw new Exception("鏈嶅姟鍣ㄨ繑鍥為敊璇唬鐮�: " + code);
+ }
+ } else {
+ throw new Exception("HTTP閿欒浠g爜: " + responseCode);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ protected void done() {
+ try {
+ updateAvailable = get();
+
+ if (updateAvailable) {
+ showUpdateAvailable();
+ statusMessageLabel.setText("妫�鏌ュ畬鎴愶紝鍙戠幇鏂扮増鏈彲鐢�");
+ } else {
+ showUpToDate();
+ statusMessageLabel.setText("妫�鏌ュ畬鎴愶紝绯荤粺宸叉槸鏈�鏂扮増鏈�");
+ }
+
+ // 鎭㈠鎸夐挳鐘舵��
+ checkUpdateButton.setText(originalText);
+ checkUpdateButton.setEnabled(true);
+
+ // 3绉掑悗鎭㈠鍘熸秷鎭�
+ Timer restoreTimer = new Timer(3000, e2 -> {
+ if (updateAvailable) {
+ statusMessageLabel.setText(releaseNotes.isEmpty() ?
+ "鏈夋柊鐗堟湰鍙敤锛屽缓璁洿鏂颁互鑾峰緱鏇村ソ鐨勪綋楠屽拰鍔熻兘銆�" : releaseNotes);
+ } else {
+ statusMessageLabel.setText("鎮ㄧ殑绯荤粺杩愯鐨勬槸鏈�鏂扮ǔ瀹氱増鏈紝鎵�鏈夊姛鑳芥甯歌繍琛屻��");
+ }
+ });
+ restoreTimer.setRepeats(false);
+ restoreTimer.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ checkUpdateButton.setText(originalText);
+ checkUpdateButton.setEnabled(true);
+ statusTitleLabel.setText("妫�鏌ュけ璐�");
+ statusMessageLabel.setText("妫�鏌ユ洿鏂板け璐ワ紝璇锋鏌ョ綉缁滃悗閲嶈瘯銆�");
+
+ JOptionPane.showMessageDialog(banbenguanli.this,
+ "妫�鏌ユ洿鏂板け璐�: " + e.getMessage(), "閿欒", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ };
+
+ worker.execute();
+ }
+
+ private void requestLoginToken() {
+ SwingWorker<String, Void> worker = new SwingWorker<String, Void>() {
+ @Override
+ protected String doInBackground() throws Exception {
+ try {
+ URL url = new URL(LOGIN_URL);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/json");
+ connection.setConnectTimeout(10000);
+ connection.setReadTimeout(15000);
+ connection.setDoOutput(true);
+
+ // 鏋勫缓鐧诲綍鏁版嵁
+ String loginData = "username=" + URLEncoder.encode(LOGIN_USERNAME, "UTF-8") +
+ "&password=" + URLEncoder.encode(LOGIN_PASSWORD, "UTF-8");
+ connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+ OutputStream os = connection.getOutputStream();
+ os.write(loginData.getBytes());
+ os.flush();
+
+ int responseCode = connection.getResponseCode();
+ if (responseCode == 200) {
+ BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ String inputLine;
+ StringBuilder response = new StringBuilder();
+
+ while ((inputLine = in.readLine()) != null) {
+ response.append(inputLine);
+ }
+ in.close();
+
+ String jsonResponse = response.toString();
+ int code = extractJsonInt(jsonResponse, "code");
+
+ if (code == 0) {
+ String tokenType = extractJsonValue(jsonResponse, "tokentype");
+ String token = extractJsonValue(jsonResponse, "token");
+ return tokenType + " " + token;
+ } else {
+ throw new Exception("鐧诲綍澶辫触锛岄敊璇唬鐮�: " + code);
+ }
+ } else {
+ throw new Exception("HTTP閿欒浠g爜: " + responseCode);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ @Override
+ protected void done() {
+ try {
+ loginToken = get();
+ statusMessageLabel.setText("姝e湪涓嬭浇鏈�鏂板畨瑁呭寘锛岃绋嶅��...");
+ downloadPackage();
+ } catch (Exception e) {
+ e.printStackTrace();
+ handleDownloadError("鑾峰彇鎺堟潈澶辫触锛岃绋嶅悗閲嶈瘯銆�");
+ }
+ }
+ };
+
+ worker.execute();
+ }
+
+ private void startUpdate() {
+ if (!updateAvailable || downloadUrl.isEmpty()) {
+ JOptionPane.showMessageDialog(this,
+ "鏃犳硶鏇存柊锛氫笅杞藉湴鍧�鏃犳晥", "閿欒", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+
+ // 绂佺敤鎸夐挳
+ checkUpdateButton.setEnabled(false);
+ updateButton.setEnabled(false);
+ updateButton.setText("鏇存柊涓�...");
+
+ // 鏄剧ず涓嬭浇杩涘害
+ progressPanel.setVisible(true);
+ downloadProgressBar.setValue(0);
+ progressPercentLabel.setText("0%");
+
+ statusTitleLabel.setText("鏇存柊涓�");
+ statusMessageLabel.setText("姝e湪鍑嗗涓嬭浇锛岃绋嶅��...");
+
+ // 璇锋眰鐧诲綍token
+ requestLoginToken();
+ }
+
+ private void downloadPackage() {
+ SwingWorker<Void, Integer> downloadWorker = new SwingWorker<Void, Integer>() {
+ @Override
+ protected Void doInBackground() throws Exception {
+ System.out.println("寮�濮嬩笅杞斤紝URL: " + downloadUrl);
+ System.out.println("浣跨敤鐨凾oken: " + loginToken);
+ try {
+ URL url = new URL(downloadUrl);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+
+
+ // 娣诲姞璁よ瘉澶�
+ if (!loginToken.isEmpty()) {
+ connection.setRequestProperty("Authorization", loginToken);
+ System.out.println("璁剧疆Authorization澶�: " + loginToken);
+ }
+
+ connection.setConnectTimeout(10000);
+ connection.setReadTimeout(30000);
+
+ int fileSize = connection.getContentLength();
+
+ // 鍒涘缓涓嬭浇鐩綍
+ File downloadDir = new File("downloads");
+ if (!downloadDir.exists()) {
+ downloadDir.mkdirs();
+ }
+
+ // 鍒涘缓杈撳嚭鏂囦欢
+ String fileName = "Issue_cards_" + latestVersion + ".apk";
+ File outputFile = new File(downloadDir, fileName);
+
+ try (InputStream inputStream = connection.getInputStream();
+ FileOutputStream outputStream = new FileOutputStream(outputFile)) {
+
+ byte[] buffer = new byte[4096];
+ int bytesRead;
+ long totalBytesRead = 0;
+
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ totalBytesRead += bytesRead;
+
+ // 璁$畻骞跺彂甯冭繘搴�
+ int progress = 0;
+ if (fileSize > 0) {
+ progress = (int) (totalBytesRead * 100 / fileSize);
+ } else {
+ // 濡傛灉鏃犳硶鑾峰彇鏂囦欢澶у皬锛屼娇鐢ㄦā鎷熻繘搴�
+ progress += (int) (Math.random() * 8);
+ if (progress >= 100) progress = 100;
+ }
+
+ publish(progress);
+
+ // 妯℃嫙涓嬭浇閫熷害
+ Thread.sleep(50);
+
+ if (isCancelled()) {
+ break;
+ }
+ }
+ }
+
+ connection.disconnect();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw e;
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void process(java.util.List<Integer> chunks) {
+ int progress = chunks.get(chunks.size() - 1);
+ downloadProgressBar.setValue(progress);
+ progressPercentLabel.setText(progress + "%");
+ }
+
+ @Override
+ protected void done() {
+ try {
+ get(); // 妫�鏌ユ槸鍚︽湁寮傚父
+
+ // 涓嬭浇瀹屾垚
+ downloadProgressBar.setValue(100);
+ progressPercentLabel.setText("100%");
+
+ // 鏇存柊瀹屾垚
+ SwingUtilities.invokeLater(() -> {
+ finishUpdate();
+ });
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ handleDownloadError("涓嬭浇澶辫触锛岃妫�鏌ョ綉缁滃悗閲嶈瘯銆�");
+ }
+ }
+ };
+
+ downloadWorker.execute();
+ }
+
+ private void finishUpdate() {
+ // 闅愯棌杩涘害鏉�
+ progressPanel.setVisible(false);
+
+ updateButton.setText("鏇存柊瀹屾垚");
+ updateButton.setBackground(new Color(149, 165, 166));
+
+ // 鏇存柊鐗堟湰淇℃伅
+ currentVersion = latestVersion;
+ currentDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+ updateAvailable = false;
+ updateVersionInfo();
+
+ // 鏄剧ず鎴愬姛娑堟伅
+ statusTitleLabel.setText("鏇存柊瀹屾垚");
+ statusMessageLabel.setText("绯荤粺宸叉垚鍔熸洿鏂板埌鏈�鏂扮増鏈紝鎵�鏈夊姛鑳藉凡浼樺寲銆�");
+
+ // 閲嶇疆鐘舵��
+ checkUpdateButton.setEnabled(true);
+ updateButton.setEnabled(false);
+
+ // 娓呯悊涓存椂鏁版嵁
+ downloadUrl = "";
+ releaseNotes = "";
+ loginToken = "";
+
+ JOptionPane.showMessageDialog(banbenguanli.this,
+ "鏇存柊瀹屾垚锛佸畨瑁呭寘宸蹭笅杞藉埌 downloads 鏂囦欢澶广��",
+ "鏇存柊鎴愬姛", JOptionPane.INFORMATION_MESSAGE);
+ }
+
+ private void handleDownloadError(String message) {
+ progressPanel.setVisible(false);
+ updateButton.setText("绔嬪嵆鏇存柊");
+ updateButton.setEnabled(updateAvailable);
+ checkUpdateButton.setEnabled(true);
+
+ statusTitleLabel.setText("鏇存柊澶辫触");
+ statusMessageLabel.setText(message);
+
+ JOptionPane.showMessageDialog(this, message, "閿欒", JOptionPane.ERROR_MESSAGE);
+ }
+
+ // 杩涘害闈㈡澘寮曠敤
+ private JPanel progressPanel;
+
+
+
+ // 闈欐�佹柟娉曪細鏄剧ず鐗堟湰绠$悊瀵硅瘽妗�
+ public static void showVersionManagementDialog(JFrame parent) {
+ SwingUtilities.invokeLater(() -> {
+ banbenguanli dialog = new banbenguanli(parent);
+ dialog.setVisible(true);
+ });
+ }
+
}
\ No newline at end of file
diff --git a/src/xitongshezhi/lishijilu.java b/src/xitongshezhi/lishijilu.java
index 4765bc8..77cb8ae 100644
--- a/src/xitongshezhi/lishijilu.java
+++ b/src/xitongshezhi/lishijilu.java
@@ -1,379 +1,175 @@
package xitongshezhi;
import javax.swing.*;
-import javax.swing.table.DefaultTableModel;
import java.awt.*;
-import java.awt.event.*;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.List;
+import java.io.*;
+import java.util.Properties;
-public class lishijilu extends JFrame {
+@SuppressWarnings("serial")
+public class lishijilu extends JDialog {
+ // 灞忓箷灏哄甯搁噺 - 閫傞厤7瀵哥珫灞�
+ private static final int SCREEN_WIDTH = 480;
+ private static final int SCREEN_HEIGHT = 800;
+
+ // 棰滆壊甯搁噺 - 缁熶竴浣跨敤kacaoguanli.java涓殑棰滆壊瀹氫箟
+ private static final Color PRIMARY_COLOR = new Color(52, 152, 219);
+ private static final Color DARK_COLOR = new Color(15, 28, 48);
+ private static final Color DARK_LIGHT_COLOR = new Color(26, 43, 68);
+ private static final Color TEXT_COLOR = new Color(224, 224, 224);
+ private static final Color TEXT_LIGHT_COLOR = new Color(160, 200, 255);
+
private JPanel mainPanel;
private JLabel titleLabel;
private JButton backButton;
- // 鎺у埗闈㈡澘缁勪欢
- private JPanel controlPanel;
- private JLabel totalRecordsLabel;
- private JLabel pickupCountLabel;
- private JLabel returnCountLabel;
- private JLabel adminCountLabel;
- private JButton refreshButton;
- private JButton clearButton;
+ // 鏂囨湰鍩熺粍浠�
+ private JScrollPane textScrollPane;
+ private JTextArea contentTextArea;
- // 琛ㄦ牸缁勪欢
- private JScrollPane tableScrollPane;
- private JTable historyTable;
- private DefaultTableModel tableModel;
- private JLabel displayCountLabel;
-
- // 鍘嗗彶璁板綍鏁版嵁
- private List<HistoryRecord> historyRecords;
- private final int MAX_RECORDS = 100;
-
- // 棰滆壊瀹氫箟
- private final Color BACKGROUND_COLOR = new Color(15, 28, 48);
- private final Color CARD_COLOR = new Color(26, 43, 68);
- private final Color PRIMARY_COLOR = new Color(52, 152, 219);
- private final Color SECONDARY_COLOR = new Color(46, 204, 113);
- private final Color DANGER_COLOR = new Color(231, 76, 60);
- private final Color WARNING_COLOR = new Color(243, 156, 18);
- private final Color TEXT_COLOR = new Color(224, 224, 224);
- private final Color TEXT_LIGHT_COLOR = new Color(160, 200, 255);
-
- public lishijilu() {
- historyRecords = new ArrayList<>();
+ public lishijilu(JFrame parent) {
+ super(parent, "", true);
initializeUI();
setupEventListeners();
- loadDemoData(); // 鍔犺浇婕旂ず鏁版嵁
- updateDisplay();
+ loadLogContent(); // 鍔犺浇鏃ュ織鍐呭
}
private void initializeUI() {
- // 璁剧疆绐楀彛灞炴�� - 7瀵哥珫灞� (480x800)
- setTitle("鍘嗗彶璁板綍 - UWB浜哄憳瀹氫綅鍗″彂鍗℃満绠$悊绯荤粺");
- setSize(480, 800);
- setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- setLocationRelativeTo(null);
+ // 璁剧疆瀵硅瘽妗嗗睘鎬�
+ setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
+ setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ setLocationRelativeTo(getParent());
setResizable(false);
- // 璁剧疆涓嶉�忔槑鑳屾櫙
- getContentPane().setBackground(BACKGROUND_COLOR);
+ // 璁剧疆绯荤粺澶栬
+ try {
+ UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
// 涓婚潰鏉�
mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
- mainPanel.setBackground(BACKGROUND_COLOR);
- mainPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
+ mainPanel.setBackground(DARK_COLOR);
+ mainPanel.setOpaque(true);
+ mainPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
// 鍒涘缓椤堕儴鏍囬鏍�
JPanel headerPanel = createHeaderPanel();
- // 鍒涘缓鎺у埗闈㈡澘
- controlPanel = createControlPanel();
-
- // 鍒涘缓琛ㄦ牸鍖哄煙
- JPanel tablePanel = createTablePanel();
+ // 鍒涘缓鏂囨湰鍖哄煙
+ JPanel contentPanel = createContentPanel();
mainPanel.add(headerPanel, BorderLayout.NORTH);
- mainPanel.add(controlPanel, BorderLayout.CENTER);
- mainPanel.add(tablePanel, BorderLayout.SOUTH);
+ mainPanel.add(contentPanel, BorderLayout.CENTER);
- add(mainPanel);
+ getContentPane().add(mainPanel);
}
private JPanel createHeaderPanel() {
- JPanel panel = new JPanel(new BorderLayout());
- panel.setBackground(BACKGROUND_COLOR);
- panel.setPreferredSize(new Dimension(464, 40));
+ JPanel headerPanel = new JPanel(new BorderLayout());
+ headerPanel.setOpaque(false);
+ headerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 12, 0));
// 鏍囬
titleLabel = new JLabel("鍘嗗彶璁板綍");
- titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
+ titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 22));
titleLabel.setForeground(TEXT_COLOR);
- titleLabel.setIcon(createIcon("馃摐", 20));
- // 杩斿洖鎸夐挳
- backButton = new JButton("杩斿洖");
- backButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));
- backButton.setBackground(new Color(52, 152, 219, 50));
- backButton.setForeground(PRIMARY_COLOR);
- backButton.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(52, 152, 219, 75), 1),
- BorderFactory.createEmptyBorder(6, 12, 6, 12)
- ));
+ // 杩斿洖鎸夐挳 - 浣跨敤涓嶉�忔槑璁捐
+ backButton = new JButton("鍏抽棴");
+ backButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
+ backButton.setBackground(PRIMARY_COLOR);
+ backButton.setForeground(Color.WHITE);
+ backButton.setOpaque(true);
backButton.setFocusPainted(false);
+ backButton.setBorder(BorderFactory.createEmptyBorder(8, 16, 8, 16));
backButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
- panel.add(titleLabel, BorderLayout.WEST);
- panel.add(backButton, BorderLayout.EAST);
-
- return panel;
- }
-
- private JPanel createControlPanel() {
- JPanel panel = new JPanel(new BorderLayout());
- panel.setBackground(CARD_COLOR);
- panel.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(52, 152, 219, 25), 1),
- BorderFactory.createEmptyBorder(12, 12, 12, 12)
- ));
- panel.setPreferredSize(new Dimension(464, 80));
-
- // 缁熻淇℃伅闈㈡澘
- JPanel statsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 15, 0));
- statsPanel.setBackground(CARD_COLOR);
-
- // 鎬昏褰�
- JPanel totalPanel = createStatItem("鎬昏褰�", "0");
- totalRecordsLabel = (JLabel) ((JPanel) totalPanel.getComponent(0)).getComponent(0);
-
- // 鍙栧崱鏁伴噺
- JPanel pickupPanel = createStatItem("鍙栧崱", "0");
- pickupCountLabel = (JLabel) ((JPanel) pickupPanel.getComponent(0)).getComponent(0);
-
- // 杩樺崱鏁伴噺
- JPanel returnPanel = createStatItem("杩樺崱", "0");
- returnCountLabel = (JLabel) ((JPanel) returnPanel.getComponent(0)).getComponent(0);
-
- // 绠$悊鍛樻搷浣�
- JPanel adminPanel = createStatItem("绠$悊鍛樻搷浣�", "0");
- adminCountLabel = (JLabel) ((JPanel) adminPanel.getComponent(0)).getComponent(0);
-
- statsPanel.add(totalPanel);
- statsPanel.add(pickupPanel);
- statsPanel.add(returnPanel);
- statsPanel.add(adminPanel);
-
- // 鎸夐挳闈㈡澘
- JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 8, 0));
- buttonPanel.setBackground(CARD_COLOR);
-
- // 鍒锋柊鎸夐挳
- refreshButton = new JButton("鍒锋柊");
- refreshButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));
- refreshButton.setBackground(new Color(46, 204, 113, 50));
- refreshButton.setForeground(SECONDARY_COLOR);
- refreshButton.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(46, 204, 113, 75), 1),
- BorderFactory.createEmptyBorder(6, 12, 6, 12)
- ));
- refreshButton.setFocusPainted(false);
- refreshButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
-
- // 娓呯┖鎸夐挳
- clearButton = new JButton("娓呯┖");
- clearButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));
- clearButton.setBackground(new Color(231, 76, 60, 50));
- clearButton.setForeground(DANGER_COLOR);
- clearButton.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(231, 76, 60, 75), 1),
- BorderFactory.createEmptyBorder(6, 12, 6, 12)
- ));
- clearButton.setFocusPainted(false);
- clearButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
-
- buttonPanel.add(refreshButton);
- buttonPanel.add(clearButton);
-
- panel.add(statsPanel, BorderLayout.WEST);
- panel.add(buttonPanel, BorderLayout.EAST);
-
- return panel;
- }
-
- private JPanel createStatItem(String label, String value) {
- JPanel panel = new JPanel();
- panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
- panel.setBackground(CARD_COLOR);
- panel.setAlignmentX(Component.CENTER_ALIGNMENT);
-
- JLabel valueLabel = new JLabel(value);
- valueLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 16));
- valueLabel.setForeground(TEXT_COLOR);
- valueLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
-
- JLabel nameLabel = new JLabel(label);
- nameLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
- nameLabel.setForeground(TEXT_LIGHT_COLOR);
- nameLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
-
- panel.add(valueLabel);
- panel.add(nameLabel);
-
- return panel;
- }
-
- private JPanel createTablePanel() {
- JPanel panel = new JPanel(new BorderLayout());
- panel.setBackground(CARD_COLOR);
- panel.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(52, 152, 219, 25), 1),
- BorderFactory.createEmptyBorder(12, 12, 12, 12)
- ));
- panel.setPreferredSize(new Dimension(464, 600));
-
- // 鍒涘缓琛ㄦ牸
- String[] columnNames = {"鏃堕棿", "鍗℃Ы缂栧彿", "鎿嶄綔", "鎿嶄綔瀵硅薄"};
- tableModel = new DefaultTableModel(columnNames, 0) {
- @Override
- public boolean isCellEditable(int row, int column) {
- return false; // 琛ㄦ牸涓嶅彲缂栬緫
+ // 杩斿洖鎸夐挳鎮仠鏁堟灉
+ backButton.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseEntered(java.awt.event.MouseEvent evt) {
+ backButton.setBackground(brighterColor(PRIMARY_COLOR));
}
- };
+
+ public void mouseExited(java.awt.event.MouseEvent evt) {
+ backButton.setBackground(PRIMARY_COLOR);
+ }
+ });
- historyTable = new JTable(tableModel);
- historyTable.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
- historyTable.setRowHeight(25);
- historyTable.setSelectionBackground(new Color(52, 152, 219, 100));
- historyTable.setGridColor(new Color(255, 255, 255, 50));
- historyTable.setShowGrid(true);
- historyTable.setIntercellSpacing(new Dimension(1, 1));
+ JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ titlePanel.setOpaque(false);
+ titlePanel.add(titleLabel);
- // 璁剧疆琛ㄥご
- historyTable.getTableHeader().setFont(new Font("Microsoft YaHei", Font.BOLD, 11));
- historyTable.getTableHeader().setBackground(new Color(15, 28, 48, 200));
- historyTable.getTableHeader().setForeground(TEXT_LIGHT_COLOR);
- historyTable.getTableHeader().setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, new Color(52, 152, 219, 75)));
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+ buttonPanel.setOpaque(false);
+ buttonPanel.add(backButton);
- // 璁剧疆鍒楀
- historyTable.getColumnModel().getColumn(0).setPreferredWidth(150); // 鏃堕棿
- historyTable.getColumnModel().getColumn(1).setPreferredWidth(80); // 鍗℃Ы缂栧彿
- historyTable.getColumnModel().getColumn(2).setPreferredWidth(60); // 鎿嶄綔
- historyTable.getColumnModel().getColumn(3).setPreferredWidth(80); // 鎿嶄綔瀵硅薄
+ headerPanel.add(titlePanel, BorderLayout.WEST);
+ headerPanel.add(buttonPanel, BorderLayout.EAST);
- // 鑷畾涔夋覆鏌撳櫒
- historyTable.setDefaultRenderer(Object.class, new HistoryTableCellRenderer());
+ return headerPanel;
+ }
+
+ private JPanel createContentPanel() {
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.setBackground(DARK_LIGHT_COLOR);
+ panel.setOpaque(true);
+ panel.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createLineBorder(new Color(52, 152, 219, 26)),
+ BorderFactory.createEmptyBorder(12, 12, 12, 12)
+ ));
- // 婊氬姩闈㈡澘
- tableScrollPane = new JScrollPane(historyTable);
- tableScrollPane.setBorder(BorderFactory.createEmptyBorder());
- tableScrollPane.getViewport().setBackground(new Color(26, 43, 68, 200));
+ // 鍐呭鏍囬
+ JPanel contentHeader = new JPanel(new BorderLayout());
+ contentHeader.setOpaque(false);
+ contentHeader.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(255, 255, 255, 26)),
+ BorderFactory.createEmptyBorder(0, 0, 8, 0)
+ ));
- // 鑷畾涔夋粴鍔ㄦ潯
- JScrollBar verticalScrollBar = tableScrollPane.getVerticalScrollBar();
- verticalScrollBar.setBackground(CARD_COLOR);
- verticalScrollBar.setUnitIncrement(16);
+ JLabel contentTitle = new JLabel("鏃ュ織鍐呭");
+ contentTitle.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
+ contentTitle.setForeground(TEXT_COLOR);
+
+ contentHeader.add(contentTitle, BorderLayout.WEST);
+
+ // 鍒涘缓鏂囨湰鍩�
+ contentTextArea = new JTextArea();
+ contentTextArea.setEditable(false);
+ contentTextArea.setBackground(DARK_LIGHT_COLOR);
+ contentTextArea.setForeground(TEXT_COLOR);
+ contentTextArea.setFont(new Font("瀹嬩綋", Font.PLAIN, 12));
+ contentTextArea.setLineWrap(true);
+ contentTextArea.setWrapStyleWord(true);
+ contentTextArea.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
+
+ // 鍒涘缓婊氬姩闈㈡澘
+ textScrollPane = new JScrollPane(contentTextArea);
+ textScrollPane.setBorder(BorderFactory.createEmptyBorder());
+ textScrollPane.getVerticalScrollBar().setUnitIncrement(16);
+ textScrollPane.setOpaque(false);
+ textScrollPane.getViewport().setOpaque(false);
// 搴曢儴淇℃伅鏍�
JPanel footerPanel = new JPanel(new BorderLayout());
- footerPanel.setBackground(CARD_COLOR);
+ footerPanel.setBackground(DARK_LIGHT_COLOR);
+ footerPanel.setOpaque(true);
footerPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, new Color(255, 255, 255, 25)));
- footerPanel.setPreferredSize(new Dimension(440, 30));
+ footerPanel.setPreferredSize(new Dimension(432, 30));
- JLabel infoLabel = new JLabel("鏄剧ず鏈�杩�");
- infoLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
- infoLabel.setForeground(TEXT_LIGHT_COLOR);
-
- displayCountLabel = new JLabel("0");
- displayCountLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 11));
- displayCountLabel.setForeground(TEXT_LIGHT_COLOR);
-
- JLabel recordsLabel = new JLabel("鏉¤褰�");
- recordsLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
- recordsLabel.setForeground(TEXT_LIGHT_COLOR);
-
- JPanel countPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
- countPanel.setBackground(CARD_COLOR);
- countPanel.add(infoLabel);
- countPanel.add(displayCountLabel);
- countPanel.add(recordsLabel);
-
- JLabel noteLabel = new JLabel("鏈�澶氫繚鐣欐渶杩�100鏉¤褰�");
+ JLabel noteLabel = new JLabel("鏈�澶氫繚鐣欐渶杩�1000鏉¤褰�");
noteLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
noteLabel.setForeground(TEXT_LIGHT_COLOR);
+ noteLabel.setOpaque(false);
- footerPanel.add(countPanel, BorderLayout.WEST);
footerPanel.add(noteLabel, BorderLayout.EAST);
- panel.add(tableScrollPane, BorderLayout.CENTER);
+ panel.add(contentHeader, BorderLayout.NORTH);
+ panel.add(textScrollPane, BorderLayout.CENTER);
panel.add(footerPanel, BorderLayout.SOUTH);
return panel;
- }
-
- // 鑷畾涔夎〃鏍煎崟鍏冩牸娓叉煋鍣�
- private class HistoryTableCellRenderer extends DefaultTableCellRenderer {
- @Override
- public Component getTableCellRendererComponent(JTable table, Object value,
- boolean isSelected, boolean hasFocus,
- int row, int column) {
- Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
-
- // 璁剧疆鍩烘湰鏍峰紡
- comp.setBackground(row % 2 == 0 ?
- new Color(26, 43, 68, 200) :
- new Color(255, 255, 255, 10));
- comp.setForeground(TEXT_COLOR);
-
- // 璁剧疆瀛椾綋
- if (column == 0) { // 鏃堕棿鍒椾娇鐢ㄧ瓑瀹藉瓧浣�
- comp.setFont(new Font("Courier New", Font.PLAIN, 10));
- } else {
- comp.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
- }
-
- // 鎿嶄綔鍒楃壒娈婂鐞�
- if (column == 2 && value != null) {
- JLabel label = new JLabel(value.toString());
- label.setOpaque(true);
- label.setHorizontalAlignment(SwingConstants.CENTER);
-
- if (value.toString().equals("鍙栧崱")) {
- label.setBackground(new Color(52, 152, 219, 50));
- label.setForeground(PRIMARY_COLOR);
- label.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(52, 152, 219, 75), 1),
- BorderFactory.createEmptyBorder(2, 8, 2, 8)
- ));
- } else if (value.toString().equals("杩樺崱")) {
- label.setBackground(new Color(46, 204, 113, 50));
- label.setForeground(SECONDARY_COLOR);
- label.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(46, 204, 113, 75), 1),
- BorderFactory.createEmptyBorder(2, 8, 2, 8)
- ));
- }
-
- if (isSelected) {
- label.setBackground(new Color(52, 152, 219, 100));
- }
-
- return label;
- }
-
- // 鎿嶄綔瀵硅薄鍒楃壒娈婂鐞�
- if (column == 3 && value != null) {
- JLabel label = new JLabel(value.toString());
- label.setOpaque(true);
- label.setHorizontalAlignment(SwingConstants.CENTER);
-
- if (value.toString().equals("绯荤粺")) {
- label.setBackground(new Color(149, 165, 166, 50));
- label.setForeground(new Color(149, 165, 166));
- label.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(149, 165, 166, 75), 1),
- BorderFactory.createEmptyBorder(2, 8, 2, 8)
- ));
- } else if (value.toString().equals("绠$悊鍛�")) {
- label.setBackground(new Color(243, 156, 18, 50));
- label.setForeground(WARNING_COLOR);
- label.setBorder(BorderFactory.createCompoundBorder(
- BorderFactory.createLineBorder(new Color(243, 156, 18, 75), 1),
- BorderFactory.createEmptyBorder(2, 8, 2, 8)
- ));
- }
-
- if (isSelected) {
- label.setBackground(new Color(52, 152, 219, 100));
- }
-
- return label;
- }
-
- return comp;
- }
}
private void setupEventListeners() {
@@ -381,225 +177,80 @@
backButton.addActionListener(e -> {
dispose();
});
-
- // 鍒锋柊鎸夐挳
- refreshButton.addActionListener(e -> {
- refreshData();
- });
-
- // 娓呯┖鎸夐挳
- clearButton.addActionListener(e -> {
- clearAllRecords();
- });
}
- // 鍘嗗彶璁板綍绫�
- private static class HistoryRecord {
- long id;
- String timestamp;
- int slotId;
- String operation; // "pickup" 鎴� "return"
- int operator; // 0=绯荤粺, 1=绠$悊鍛�
+ // 鍔犺浇鏃ュ織鍐呭
+ private void loadLogContent() {
+ File logFile = new File("log.properties");
- HistoryRecord(long id, String timestamp, int slotId, String operation, int operator) {
- this.id = id;
- this.timestamp = timestamp;
- this.slotId = slotId;
- this.operation = operation;
- this.operator = operator;
+ if (!logFile.exists()) {
+ contentTextArea.setText("鏃ュ織鏂囦欢涓嶅瓨鍦ㄣ��");
+ return;
}
- }
-
- // 鍔犺浇婕旂ず鏁版嵁
- private void loadDemoData() {
- if (historyRecords.isEmpty()) {
- generateDemoData();
- }
- }
-
- // 鐢熸垚婕旂ず鏁版嵁
- private void generateDemoData() {
- String[] operations = {"pickup", "return"};
- int[] operators = {0, 1}; // 0=绯荤粺, 1=绠$悊鍛�
- long baseTime = System.currentTimeMillis() - (30L * 24 * 60 * 60 * 1000); // 30澶╁墠寮�濮�
- for (int i = 0; i < 50; i++) {
- int randomSlot = (int) (Math.random() * 60) + 1;
- String randomOperation = operations[(int) (Math.random() * operations.length)];
- int randomOperator = operators[(int) (Math.random() * operators.length)];
- long randomTime = baseTime + (long) (Math.random() * 30 * 24 * 60 * 60 * 1000);
+ Properties logProps = new Properties();
+ try (FileInputStream in = new FileInputStream(logFile)) {
+ logProps.load(in);
- historyRecords.add(new HistoryRecord(
- randomTime,
- new Date(randomTime).toInstant().toString(),
- randomSlot,
- randomOperation,
- randomOperator
- ));
- }
-
- // 鎸夋椂闂存帓搴忥紙鏈�鏂扮殑鍦ㄥ墠闈級
- historyRecords.sort((a, b) -> Long.compare(b.id, a.id));
-
- // 闄愬埗涓烘渶澶ц褰曟暟
- if (historyRecords.size() > MAX_RECORDS) {
- historyRecords = historyRecords.subList(0, MAX_RECORDS);
- }
- }
-
- // 鏍煎紡鍖栨椂闂存樉绀�
- private String formatTime(String isoString) {
- try {
- SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
- SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- Date date = inputFormat.parse(isoString);
- return outputFormat.format(date);
- } catch (Exception e) {
- return isoString;
- }
- }
-
- // 鑾峰彇鎿嶄綔鏄剧ず鏂囨湰
- private String getOperationText(String operation) {
- return "pickup".equals(operation) ? "鍙栧崱" : "杩樺崱";
- }
-
- // 鑾峰彇鎿嶄綔瀵硅薄鏄剧ず鏂囨湰
- private String getOperatorText(int operator) {
- return operator == 0 ? "绯荤粺" : "绠$悊鍛�";
- }
-
- // 鏇存柊鏄剧ず
- private void updateDisplay() {
- // 鏇存柊琛ㄦ牸
- tableModel.setRowCount(0);
-
- for (HistoryRecord record : historyRecords) {
- tableModel.addRow(new Object[]{
- formatTime(record.timestamp),
- record.slotId,
- getOperationText(record.operation),
- getOperatorText(record.operator)
- });
- }
-
- // 鏇存柊缁熻淇℃伅
- updateStats();
- }
-
- // 鏇存柊缁熻淇℃伅
- private void updateStats() {
- int total = historyRecords.size();
- int pickupCount = (int) historyRecords.stream()
- .filter(record -> "pickup".equals(record.operation))
- .count();
- int returnCount = (int) historyRecords.stream()
- .filter(record -> "return".equals(record.operation))
- .count();
- int adminCount = (int) historyRecords.stream()
- .filter(record -> record.operator == 1)
- .count();
-
- totalRecordsLabel.setText(String.valueOf(total));
- pickupCountLabel.setText(String.valueOf(pickupCount));
- returnCountLabel.setText(String.valueOf(returnCount));
- adminCountLabel.setText(String.valueOf(adminCount));
- displayCountLabel.setText(String.valueOf(total));
- }
-
- // 鍒锋柊鏁版嵁
- private void refreshData() {
- String originalText = refreshButton.getText();
-
- // 鏄剧ず鍒锋柊涓姸鎬�
- refreshButton.setText("鍒锋柊涓�...");
- refreshButton.setEnabled(false);
-
- // 妯℃嫙鏁版嵁鍒锋柊寤惰繜
- Timer timer = new Timer(800, e -> {
- updateDisplay();
-
- // 鎭㈠鎸夐挳鐘舵��
- refreshButton.setText(originalText);
- refreshButton.setEnabled(true);
- });
- timer.setRepeats(false);
- timer.start();
- }
-
- // 娓呯┖鎵�鏈夎褰�
- private void clearAllRecords() {
- int result = JOptionPane.showConfirmDialog(
- this,
- "纭畾瑕佹竻绌烘墍鏈夊巻鍙茶褰曞悧锛熸鎿嶄綔涓嶅彲鎭㈠銆�",
- "纭娓呯┖",
- JOptionPane.YES_NO_OPTION,
- JOptionPane.WARNING_MESSAGE
- );
-
- if (result == JOptionPane.YES_OPTION) {
- historyRecords.clear();
- updateDisplay();
- }
- }
-
- // 娣诲姞娴嬭瘯璁板綍锛堢敤浜庢紨绀猴級
- private void addTestRecord() {
- int randomSlot = (int) (Math.random() * 60) + 1;
- String randomOperation = Math.random() > 0.5 ? "pickup" : "return";
- int randomOperator = Math.random() > 0.7 ? 1 : 0; // 30%姒傜巼涓虹鐞嗗憳鎿嶄綔
-
- historyRecords.add(0, new HistoryRecord(
- System.currentTimeMillis(),
- new Date().toInstant().toString(),
- randomSlot,
- randomOperation,
- randomOperator
- ));
-
- // 闄愬埗涓烘渶澶ц褰曟暟
- if (historyRecords.size() > MAX_RECORDS) {
- historyRecords.remove(historyRecords.size() - 1);
- }
-
- updateDisplay();
- }
-
- // 鍒涘缓鍥炬爣锛堜娇鐢ㄦ枃鏈〃鎯呯鍙凤級
- private Icon createIcon(String emoji, int size) {
- JLabel label = new JLabel(emoji);
- label.setFont(new Font("Segoe UI Emoji", Font.PLAIN, size));
- return new Icon() {
- @Override
- public void paintIcon(Component c, Graphics g, int x, int y) {
- label.setBounds(x, y, getIconWidth(), getIconHeight());
- label.paint(g);
+ // 妫�鏌ヨ褰曟暟閲忥紝濡傛灉瓒呰繃1000鏉″垯鍒犻櫎鏃ц褰�
+ if (logProps.size() > 1000) {
+ trimLogProperties(logProps);
}
- @Override
- public int getIconWidth() {
- return size;
- }
+ // 鏋勫缓鏄剧ず鍐呭
+ StringBuilder content = new StringBuilder();
+ content.append("鏃ュ織鏂囦欢鍐呭 (").append(logProps.size()).append(" 鏉¤褰�):\n\n");
- @Override
- public int getIconHeight() {
- return size;
- }
- };
+ // 鎸夋椂闂存埑鎺掑簭鏄剧ず
+ logProps.stringPropertyNames().stream()
+ .sorted((a, b) -> Long.compare(Long.parseLong(b), Long.parseLong(a)))
+ .forEach(key -> {
+ String value = logProps.getProperty(key);
+ content.append("鏃堕棿鎴�: ").append(key).append("\n");
+ content.append("鍐呭: ").append(value).append("\n");
+ content.append("----------------------------------------\n");
+ });
+
+ contentTextArea.setText(content.toString());
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ contentTextArea.setText("鍔犺浇鏃ュ織鏂囦欢鏃跺嚭閿�: " + e.getMessage());
+ } catch (NumberFormatException e) {
+ contentTextArea.setText("鏃ュ織鏂囦欢鏍煎紡閿欒銆�");
+ }
}
- // 涓绘柟娉曟祴璇�
- public static void main(String[] args) {
- // 璁剧疆绯荤粺澶栬
- try {
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeel());
- } catch (Exception e) {
+ // 淇壀鏃ュ織灞炴�э紝鍙繚鐣欐渶鏂扮殑1000鏉¤褰�
+ private void trimLogProperties(Properties logProps) {
+ // 鎸夋椂闂存埑鎺掑簭锛屼繚鐣欐渶鏂扮殑1000鏉�
+ logProps.stringPropertyNames().stream()
+ .sorted((a, b) -> Long.compare(Long.parseLong(b), Long.parseLong(a)))
+ .skip(1000)
+ .forEach(logProps::remove);
+
+ // 淇濆瓨淇壀鍚庣殑灞炴��
+ try (FileOutputStream out = new FileOutputStream("log.properties")) {
+ logProps.store(out, "UWB浜哄憳瀹氫綅鍗″彂鍗℃満鍘嗗彶璁板綍 - 鑷姩淇壀鑷�1000鏉¤褰�");
+ } catch (IOException e) {
e.printStackTrace();
}
-
- SwingUtilities.invokeLater(() -> {
- lishijilu frame = new lishijilu();
- frame.setVisible(true);
- });
}
+
+ // 鏂板杈呭姪鏂规硶锛氫娇棰滆壊鏇翠寒
+ private Color brighterColor(Color color) {
+ int r = Math.min(255, color.getRed() + 30);
+ int g = Math.min(255, color.getGreen() + 30);
+ int b = Math.min(255, color.getBlue() + 30);
+ return new Color(r, g, b);
+ }
+
+ // 闈欐�佹柟娉曪細浠庡叾浠栭〉闈㈣皟鐢�
+ public static void showHistoryDialog(JFrame parent) {
+ SwingUtilities.invokeLater(() -> {
+ lishijilu dialog = new lishijilu(parent);
+ dialog.setVisible(true);
+ });
+ }
+
}
\ No newline at end of file
--
Gitblit v1.9.3