| bin/chuankou/SerialPortConnectionDialog$1.class | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| bin/chuankou/SerialPortConnectionDialog.class | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| bin/home/CardMachineUI$1.class | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| bin/home/CardMachineUI.class | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| bin/home/Homein.class | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| err.properties | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| log.properties | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/chuankou/SerialPortConnectionDialog.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/home/CardMachineUI.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/home/Homein.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/jiekou/lunxunkazhuangtai.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
bin/chuankou/SerialPortConnectionDialog$1.classBinary files differ
bin/chuankou/SerialPortConnectionDialog.classBinary files differ
bin/home/CardMachineUI$1.classBinary files differ
bin/home/CardMachineUI.classBinary files differ
bin/home/Homein.classBinary files differ
err.properties
@@ -1,10 +1,2 @@ #\u64CD\u4F5C\u65E5\u5FD7\u8BB0\u5F55 - \u6700\u540E\u66F4\u65B0: Fri Nov 21 15:53:26 CST 2025 #Fri Nov 21 15:53:26 CST 2025 log_1763709005376_be67189d=[2025-11-21 15\:10\:05] 取卡操作:12132232 log_1763709010792_533f9544=[2025-11-21 15\:10\:10] 取卡操作:卡槽14被管理员取卡 log_1763711606778_258ce9b3=[2025-11-21 15\:53\:26] [15\:53\:26.776] 发送失败,正在重试 (1/2) log_1763711606820_621ce6a5=[2025-11-21 15\:53\:26] [15\:53\:26.820] 发送失败,正在重试 (1/2) log_1763711606821_a4bb65ce=[2025-11-21 15\:53\:26] [15\:53\:26.821] 发送失败,正在重试 (1/2) log_1763711606822_e9cc5b23=[2025-11-21 15\:53\:26] [15\:53\:26.822] 发送失败,正在重试 (1/2) log_1763711606823_1da1f119=[2025-11-21 15\:53\:26] [15\:53\:26.823] 发送失败,正在重试 (1/2) log_1763711606824_15788a29=[2025-11-21 15\:53\:26] lunxun连续失败次数过多,暂停轮询 #\u53D1\u5361\u673A\u9519\u8BEF\u8BB0\u5F55 - \u6240\u6709\u8BB0\u5F55\u5DF2\u6E05\u7A7A #Fri Nov 21 19:35:34 CST 2025 log.properties
@@ -1,33 +1,67 @@ #\u64CD\u4F5C\u65E5\u5FD7\u8BB0\u5F55 - \u6700\u540E\u66F4\u65B0: Fri Nov 21 17:44:41 CST 2025 #Fri Nov 21 17:44:41 CST 2025 log_1763718093181_61c0dfbe=[2025-11-21 17\:41\:33] 取卡操作:卡槽13被管理员取卡 log_1763718093533_c3563f25=[2025-11-21 17\:41\:33] 取卡操作:卡槽13被管理员取卡 log_1763718147310_e84a6b5b=[2025-11-21 17\:42\:27] 取卡操作:卡槽22被管理员取卡 log_1763718150490_e2f94107=[2025-11-21 17\:42\:30] 取卡操作:卡槽23被管理员取卡 log_1763718150843_c9147690=[2025-11-21 17\:42\:30] 取卡操作:卡槽23被管理员取卡 log_1763718198841_27d9aa77=[2025-11-21 17\:43\:18] 取卡操作:卡槽12被管理员取卡 log_1763718199155_4cd5e39f=[2025-11-21 17\:43\:19] 取卡操作:卡槽12被管理员取卡 log_1763718207706_07760e2f=[2025-11-21 17\:43\:27] DDCC0008F003515AA55AA5027A7E;type2控制打开3柜门 log_1763718208053_ee80022a=[2025-11-21 17\:43\:28] 3号卡槽取卡失败 log_1763718208759_e8be3ec0=[2025-11-21 17\:43\:28] DDCC0008F003515AA55AA5027A7E;type2控制打开3柜门 log_1763718209104_247397ce=[2025-11-21 17\:43\:29] 取卡操作:卡槽3被管理员取卡 log_1763718275945_e2a4d769=[2025-11-21 17\:44\:35] DDCC0008F012515AA55AA5027B7F;type2控制打开18柜门 log_1763718276293_034826af=[2025-11-21 17\:44\:36] 取卡操作:卡槽18被管理员取卡 log_1763718276666_18777eee=[2025-11-21 17\:44\:36] DDCC0008F017515AA55AA5027B2A;type2控制打开23柜门 log_1763718276992_c9ad983a=[2025-11-21 17\:44\:36] 取卡操作:卡槽23被管理员取卡 log_1763718277268_15912a52=[2025-11-21 17\:44\:37] DDCC0008F01C515AA55AA502BB90;type2控制打开28柜门 log_1763718277593_d9b897ba=[2025-11-21 17\:44\:37] 取卡操作:卡槽28被管理员取卡 log_1763718277892_72d570bd=[2025-11-21 17\:44\:37] DDCC0008F018515AA55AA5027BD5;type2控制打开24柜门 log_1763718278242_75327d86=[2025-11-21 17\:44\:38] 取卡操作:卡槽24被管理员取卡 log_1763718278782_a91dddda=[2025-11-21 17\:44\:38] DDCC0008F00E515AA55AA502BAA2;type2控制打开14柜门 log_1763718279143_4e4cb89a=[2025-11-21 17\:44\:39] 取卡操作:卡槽14被管理员取卡 log_1763718279202_9c58a3b9=[2025-11-21 17\:44\:39] DDCC0008F013515AA55AA502BB6F;type2控制打开19柜门 log_1763718279543_9e40ceff=[2025-11-21 17\:44\:39] 取卡操作:卡槽19被管理员取卡 log_1763718279709_4483c6c4=[2025-11-21 17\:44\:39] DDCC0008F01D515AA55AA5027B80;type2控制打开29柜门 log_1763718280043_06750db2=[2025-11-21 17\:44\:40] 取卡操作:卡槽29被管理员取卡 log_1763718280658_b6288ce6=[2025-11-21 17\:44\:40] DDCC0008F00F515AA55AA5027AB2;type2控制打开15柜门 log_1763718280993_f6f218cc=[2025-11-21 17\:44\:40] 取卡操作:卡槽15被管理员取卡 log_1763718281030_2d1edd96=[2025-11-21 17\:44\:41] DDCC0008F014515AA55AA5027B19;type2控制打开20柜门 log_1763718281392_c8b2ee8c=[2025-11-21 17\:44\:41] 取卡操作:卡槽20被管理员取卡 log_1763718281404_56d7aa71=[2025-11-21 17\:44\:41] DDCC0008F019515AA55AA502BBC5;type2控制打开25柜门 log_1763718281743_12a79e45=[2025-11-21 17\:44\:41] 取卡操作:卡槽25被管理员取卡 #\u64CD\u4F5C\u65E5\u5FD7\u8BB0\u5F55 - \u6700\u540E\u66F4\u65B0: Fri Nov 21 19:36:06 CST 2025 #Fri Nov 21 19:36:06 CST 2025 log_1763724957486_7ed8425e=[2025-11-21 19\:35\:57] 取卡操作:卡槽1被管理员取卡 log_1763724957585_8967e0b2=[2025-11-21 19\:35\:57] 取卡操作:卡槽2被管理员取卡 log_1763724957735_6574dba5=[2025-11-21 19\:35\:57] 取卡操作:卡槽3被管理员取卡 log_1763724957835_0f410589=[2025-11-21 19\:35\:57] 取卡操作:卡槽4被管理员取卡 log_1763724957935_854f0c49=[2025-11-21 19\:35\:57] 取卡操作:卡槽5被管理员取卡 log_1763724958035_36f51e22=[2025-11-21 19\:35\:58] 取卡操作:卡槽6被管理员取卡 log_1763724958135_0945adfb=[2025-11-21 19\:35\:58] 取卡操作:卡槽7被管理员取卡 log_1763724958235_280878bc=[2025-11-21 19\:35\:58] 取卡操作:卡槽8被管理员取卡 log_1763724958335_62c3daf7=[2025-11-21 19\:35\:58] 取卡操作:卡槽9被管理员取卡 log_1763724958435_09f4db94=[2025-11-21 19\:35\:58] 取卡操作:卡槽10被管理员取卡 log_1763724958534_066792c4=[2025-11-21 19\:35\:58] 取卡操作:卡槽11被管理员取卡 log_1763724958635_6099e667=[2025-11-21 19\:35\:58] 取卡操作:卡槽12被管理员取卡 log_1763724958735_83166056=[2025-11-21 19\:35\:58] 取卡操作:卡槽13被管理员取卡 log_1763724958834_1765f7e9=[2025-11-21 19\:35\:58] 取卡操作:卡槽14被管理员取卡 log_1763724958935_e316b9ce=[2025-11-21 19\:35\:58] 取卡操作:卡槽15被管理员取卡 log_1763724959085_65c537e7=[2025-11-21 19\:35\:59] 取卡操作:卡槽16被管理员取卡 log_1763724959134_aa6dc9d6=[2025-11-21 19\:35\:59] 取卡操作:卡槽17被管理员取卡 log_1763724959285_77b24bbc=[2025-11-21 19\:35\:59] 取卡操作:卡槽18被管理员取卡 log_1763724959385_64338885=[2025-11-21 19\:35\:59] 取卡操作:卡槽19被管理员取卡 log_1763724959486_5916ce74=[2025-11-21 19\:35\:59] 取卡操作:卡槽20被管理员取卡 log_1763724959585_6384a4cc=[2025-11-21 19\:35\:59] 取卡操作:卡槽21被管理员取卡 log_1763724959685_7d45eb0b=[2025-11-21 19\:35\:59] 取卡操作:卡槽22被管理员取卡 log_1763724959786_4aa7ca6f=[2025-11-21 19\:35\:59] 取卡操作:卡槽23被管理员取卡 log_1763724959885_da92954b=[2025-11-21 19\:35\:59] 取卡操作:卡槽24被管理员取卡 log_1763724959985_277f652c=[2025-11-21 19\:35\:59] 取卡操作:卡槽25被管理员取卡 log_1763724960086_aa7cf203=[2025-11-21 19\:36\:00] 取卡操作:卡槽26被管理员取卡 log_1763724960185_2848a5cc=[2025-11-21 19\:36\:00] 取卡操作:卡槽27被管理员取卡 log_1763724960287_3b4bb2ab=[2025-11-21 19\:36\:00] 取卡操作:卡槽28被管理员取卡 log_1763724960386_f261ef41=[2025-11-21 19\:36\:00] 取卡操作:卡槽29被管理员取卡 log_1763724960535_97afbeaf=[2025-11-21 19\:36\:00] 取卡操作:卡槽30被管理员取卡 log_1763724960634_8c0920c2=[2025-11-21 19\:36\:00] 取卡操作:卡槽31被管理员取卡 log_1763724960735_06ce365d=[2025-11-21 19\:36\:00] 取卡操作:卡槽32被管理员取卡 log_1763724960835_cbfa348a=[2025-11-21 19\:36\:00] 取卡操作:卡槽33被管理员取卡 log_1763724960934_0e4d07c0=[2025-11-21 19\:36\:00] 取卡操作:卡槽34被管理员取卡 log_1763724961035_8b4bd8fe=[2025-11-21 19\:36\:01] 取卡操作:卡槽35被管理员取卡 log_1763724961135_0b4d5de9=[2025-11-21 19\:36\:01] 取卡操作:卡槽36被管理员取卡 log_1763724961236_a767eee0=[2025-11-21 19\:36\:01] 取卡操作:卡槽37被管理员取卡 log_1763724961335_822c08d8=[2025-11-21 19\:36\:01] 取卡操作:卡槽38被管理员取卡 log_1763724961435_db3ec62e=[2025-11-21 19\:36\:01] 取卡操作:卡槽39被管理员取卡 log_1763724961534_5fefc851=[2025-11-21 19\:36\:01] 取卡操作:卡槽40被管理员取卡 log_1763724961635_e21db5ef=[2025-11-21 19\:36\:01] 取卡操作:卡槽41被管理员取卡 log_1763724961735_a48231c4=[2025-11-21 19\:36\:01] 取卡操作:卡槽42被管理员取卡 log_1763724961836_be19a1e4=[2025-11-21 19\:36\:01] 取卡操作:卡槽43被管理员取卡 log_1763724961935_d9a52997=[2025-11-21 19\:36\:01] 取卡操作:卡槽44被管理员取卡 log_1763724962085_81151e8b=[2025-11-21 19\:36\:02] 取卡操作:卡槽45被管理员取卡 log_1763724962186_40dd031b=[2025-11-21 19\:36\:02] 取卡操作:卡槽46被管理员取卡 log_1763724962285_2b8f9092=[2025-11-21 19\:36\:02] 取卡操作:卡槽47被管理员取卡 log_1763724962385_8abe459c=[2025-11-21 19\:36\:02] 取卡操作:卡槽48被管理员取卡 log_1763724962485_852ad173=[2025-11-21 19\:36\:02] 取卡操作:卡槽49被管理员取卡 log_1763724962585_e5e73d2c=[2025-11-21 19\:36\:02] 取卡操作:卡槽50被管理员取卡 log_1763724962685_896c53e3=[2025-11-21 19\:36\:02] 取卡操作:卡槽51被管理员取卡 log_1763724962786_ab983c5b=[2025-11-21 19\:36\:02] 取卡操作:卡槽52被管理员取卡 log_1763724962885_8687a0c3=[2025-11-21 19\:36\:02] 取卡操作:卡槽53被管理员取卡 log_1763724962985_3709588c=[2025-11-21 19\:36\:02] 取卡操作:卡槽54被管理员取卡 log_1763724963085_3f4cc469=[2025-11-21 19\:36\:03] 取卡操作:卡槽55被管理员取卡 log_1763724963185_6e98de49=[2025-11-21 19\:36\:03] 取卡操作:卡槽56被管理员取卡 log_1763724963285_41af6941=[2025-11-21 19\:36\:03] 取卡操作:卡槽57被管理员取卡 log_1763724963385_3af18a57=[2025-11-21 19\:36\:03] 取卡操作:卡槽55被管理员取卡 log_1763724963387_fe428ae2=[2025-11-21 19\:36\:03] 取卡操作:卡槽58被管理员取卡 log_1763724963535_1c1b689f=[2025-11-21 19\:36\:03] 取卡操作:卡槽59被管理员取卡 log_1763724963636_7ca29f16=[2025-11-21 19\:36\:03] 取卡操作:卡槽60被管理员取卡 log_1763724963685_d33f12b8=[2025-11-21 19\:36\:03] 取卡操作:卡槽55被管理员取卡 log_1763724963985_8ee47f7c=[2025-11-21 19\:36\:03] 取卡操作:卡槽55被管理员取卡 log_1763724964285_ddff2a15=[2025-11-21 19\:36\:04] 取卡操作:卡槽55被管理员取卡 log_1763724966171_1001bb5c=[2025-11-21 19\:36\:06] 管理员已将全部卡槽已经打开请取卡 src/chuankou/SerialPortConnectionDialog.java
@@ -183,6 +183,8 @@ exitButton.setFocusPainted(false); exitButton.setBorder(BorderFactory.createEmptyBorder(8, 20, 8, 20)); exitButton.addActionListener(e -> { // 新增:退出前确保关闭串口连接 cleanupSerialPort(); System.exit(0); }); @@ -303,14 +305,63 @@ }); } else { // 连接失败处理保持不变... // 连接失败 connectButton.setEnabled(true); connectButton.setText("连接串口"); connectButton.setBackground(SECONDARY_COLOR); statusLabel.setText("串口连接失败: " + portName); showMessage("连接失败", "无法连接到串口 " + portName, "error"); // 关闭失败的串口连接 if (serialService != null) { serialService.close(); serialService = null; } } }); } catch (Exception e) { // 异常处理保持不变... SwingUtilities.invokeLater(() -> { connectButton.setEnabled(true); connectButton.setText("连接串口"); connectButton.setBackground(SECONDARY_COLOR); statusLabel.setText("连接异常: " + e.getMessage()); showMessage("连接异常", "串口连接过程中发生错误: " + e.getMessage(), "error"); // 关闭异常的串口连接 if (serialService != null) { serialService.close(); serialService = null; } }); } }).start(); } /** * 新增:清理串口资源的方法 */ private void cleanupSerialPort() { if (serialService != null) { try { // 停止数据捕获 serialService.stopCapture(); // 停止协议解析器 if (serialService.getProtocolParser() != null) { serialService.getProtocolParser().stop(); } // 关闭串口 serialService.close(); //System.out.println("串口连接已清理"); } catch (Exception e) { System.err.println("清理串口资源时发生异常: " + e.getMessage()); } finally { serialService = null; } } } private void showMessage(String title, String message, String type) { @@ -351,7 +402,7 @@ public void dispose() { // 如果连接失败,关闭串口 if (!isConnected && serialService != null) { serialService.close(); cleanupSerialPort(); } super.dispose(); } src/home/CardMachineUI.java
@@ -87,7 +87,14 @@ initializeUI(); initializeSlots(); startUIUpdates(); // UI刷新定时器 startSerialStatusMonitoring(); // 串口状态监控 startSerialStatusMonitoring(); // 串口状态监控 setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent windowEvent) { dispose(); // 调用我们修改过的dispose方法 } }); //System.out.println("主界面初始化完成"); } catch (Exception e) { @@ -596,34 +603,67 @@ } public void dispose() { // 停止UI刷新定时器 if (uiUpdateTimer != null) { uiUpdateTimer.stop(); } // 停止串口状态监控 if (serialStatusTimer != null) { serialStatusTimer.stop(); } // 停止轮询查询 if (lunxun.isPolling()) { lunxun.stopPolling(); //System.out.println("应用程序关闭,轮询查询已停止"); } // 停止串口协议解析器(新增) if (serialProtocolParser != null) { serialProtocolParser.stop(); } // 停止串口服务 if (serialPortService != null) { serialPortService.stopCapture(); serialPortService.close(); } super.dispose(); int result = JOptionPane.showConfirmDialog(this, "确定要退出程序吗?", "确认退出", JOptionPane.YES_NO_OPTION); if (result != JOptionPane.YES_OPTION) { return; // 用户取消退出 } // 停止UI刷新定时器 if (uiUpdateTimer != null) { uiUpdateTimer.stop(); } // 停止串口状态监控 if (serialStatusTimer != null) { serialStatusTimer.stop(); } // 停止轮询查询 if (lunxun.isPolling()) { lunxun.stopPolling(); //System.out.println("应用程序关闭,轮询查询已停止"); } // 停止串口协议解析器(新增) if (serialProtocolParser != null) { serialProtocolParser.stop(); } // 停止串口服务 if (serialPortService != null) { serialPortService.stopCapture(); serialPortService.close(); } super.dispose(); // 新增:确保程序完全退出前释放单实例锁 try { // 通过反射调用 Homein 的清理方法 Class<?> homeinClass = Class.forName("home.Homein"); java.lang.reflect.Method cleanupMethod = homeinClass.getDeclaredMethod("cleanupSingleInstanceLock"); cleanupMethod.setAccessible(true); cleanupMethod.invoke(null); //System.out.println("单实例锁已释放"); } catch (Exception e) { System.err.println("释放单实例锁时发生异常: " + e.getMessage()); // 如果反射失败,尝试直接关闭端口 try { java.net.ServerSocket socket = new java.net.ServerSocket(); socket.setReuseAddress(true); socket.bind(new java.net.InetSocketAddress(9999)); socket.close(); //System.out.println("通过直接绑定方式释放端口"); } catch (Exception ex) { System.err.println("直接释放端口也失败: " + ex.getMessage()); } } // 新增:确保程序完全退出 System.exit(0); } /** src/home/Homein.java
@@ -6,9 +6,25 @@ import chushihua.Chushihua; import chushihua.SlotManager; import chushihua.lunxun; import dialog.Dingshidialog; import jiekou.lunxunkazhuangtai; import java.io.IOException; import java.net.ServerSocket; public class Homein { // 单实例锁的端口号,选择一个不常用的端口 private static final int SINGLE_INSTANCE_PORT = 9999; private static ServerSocket singleInstanceSocket; public static void main(String[] args) { // 检查是否已有实例在运行 if (!checkSingleInstance()) { Dingshidialog.showTimedDialog(null,5, "软件已经在运行中,不能重复打开!"); System.exit(0); return; } SwingUtilities.invokeLater(() -> { try { // 设置系统外观 @@ -26,6 +42,7 @@ "系统初始化失败,无法启动应用程序", "错误", JOptionPane.ERROR_MESSAGE); cleanupSingleInstanceLock(); System.exit(1); } @@ -35,9 +52,50 @@ "程序启动失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE); cleanupSingleInstanceLock(); System.exit(1); } }); } /** * 检查是否单实例运行 * @return 如果是唯一实例返回true,如果已有实例运行返回false */ private static boolean checkSingleInstance() { try { // 尝试绑定到指定端口,如果成功说明是第一个实例 singleInstanceSocket = new ServerSocket(SINGLE_INSTANCE_PORT); return true; } catch (IOException e) { // 端口已被占用,说明已有实例在运行 return false; } } /** * 清理单实例锁 - 改为公共静态方法以便外部调用 */ public static void cleanupSingleInstanceLock() { if (singleInstanceSocket != null && !singleInstanceSocket.isClosed()) { try { singleInstanceSocket.close(); //System.out.println("单实例锁已清理"); } catch (IOException e) { System.err.println("关闭单实例锁时发生异常: " + e.getMessage()); } finally { singleInstanceSocket = null; } } // 额外确保:尝试再次绑定端口来确认是否已释放 try { ServerSocket testSocket = new ServerSocket(SINGLE_INSTANCE_PORT); testSocket.close(); //System.out.println("端口确认已释放"); } catch (IOException e) { System.err.println("端口可能仍被占用: " + e.getMessage()); } } /** @@ -127,11 +185,14 @@ if (serialConnected) { // 4. 串口连接成功后,启动轮询 startPollingService(); showMainInterface(); showMainInterface(); lunxunkazhuangtai.startPolling();//启动卡状态轮询发给服务器 } else { System.err.println("串口连接失败"); // 串口连接失败已经由SerialPortConnectionDialog处理,直接退出 cleanupSingleInstanceLock(); System.exit(0); } @@ -142,6 +203,7 @@ "应用程序启动过程中发生错误: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE); cleanupSingleInstanceLock(); System.exit(1); } } @@ -267,6 +329,9 @@ mainUI.dispose(); } // 清理单实例锁 - 确保在关闭钩子中也调用 cleanupSingleInstanceLock(); //System.out.println("应用程序关闭完成"); } catch (Exception e) { src/jiekou/lunxunkazhuangtai.java
@@ -2,174 +2,245 @@ import chushihua.SlotManager; import home.Fkj; /** * 轮询卡槽状态类 * 用于定期轮询并输出所有卡槽的状态信息 */ public class lunxunkazhuangtai { private static Thread pollThread; private static volatile boolean isRunning = false; private static final int POLL_INTERVAL = 30000; // 30秒间隔 private static Thread pollThread; private static volatile boolean isRunning = false; private static volatile int pollInterval = 30000; // 30秒间隔,改为可变的 // 常量定义,避免重复创建字符串 private static final String THREAD_NAME = "SlotStatusPollingThread"; private static final String UNKNOWN = "未知"; private static final String NORMAL = "正常"; private static final String NULL_VALUE = "null"; // 状态常量 private static final String STATUS_INVALID = "0"; private static final String STATUS_STANDBY = "1"; private static final String STATUS_CHARGING = "2"; private static final String STATUS_FULL = "3"; private static final String STATUS_FAULT = "4"; private static final String STATUS_AUTH_EXPIRED = "5"; private static final String STATUS_TIMEOUT = "6"; private static final String STATUS_UNKNOWN = "-1"; // 故障常量 private static final String FAULT_NORMAL = "0"; private static final String FAULT_CARD_ERROR = "1"; private static final String FAULT_OVER_CURRENT = "2"; private static final String FAULT_DOOR_FAULT = "3"; private static final String FAULT_OVER_VOLTAGE = "4"; private static final String FAULT_UNDER_VOLTAGE = "5"; private static final String FAULT_UNKNOWN = "-1"; /** * 启动轮询线程 */ public static void startPolling() { if (isRunning) {; return; } /** * 启动轮询线程 */ public static void startPolling() { if (isRunning) { System.out.println("轮询线程已在运行中"); return; } isRunning = true; pollThread = new Thread(new PollingTask(), "SlotStatusPollingThread"); pollThread.setDaemon(true); // 设置为守护线程,当主线程结束时自动结束 pollThread.start(); } isRunning = true; pollThread = new Thread(new PollingTask(), THREAD_NAME); pollThread.setDaemon(true); pollThread.start(); System.out.println("卡槽状态轮询线程已启动,间隔: " + pollInterval + "ms"); } /** * 停止轮询线程 */ public static void stopPolling() { isRunning = false; if (pollThread != null) { pollThread.interrupt(); pollThread = null; } System.out.println("卡槽状态轮询线程已停止"); } /** * 停止轮询线程 */ public static void stopPolling() { if (!isRunning) { return; } isRunning = false; if (pollThread != null) { pollThread.interrupt(); try { // 等待线程安全结束,最多等待2秒 pollThread.join(2000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.out.println("等待轮询线程停止时被中断"); } pollThread = null; } System.out.println("卡槽状态轮询线程已停止"); } /** * 检查轮询线程是否在运行 * @return 运行状态 */ public static boolean isPolling() { return isRunning; } /** * 检查轮询线程是否在运行 * @return 运行状态 */ public static boolean isPolling() { return isRunning; } /** * 轮询任务实现 */ private static class PollingTask implements Runnable { @Override public void run() { while (isRunning && !Thread.currentThread().isInterrupted()) { try { // 输出所有卡槽状态 printAllSlotsStatus(); /** * 轮询任务实现 */ private static class PollingTask implements Runnable { @Override public void run() { System.out.println("轮询任务开始执行"); 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; } // 使用动态间隔,支持运行时调整 Thread.sleep(pollInterval); } catch (InterruptedException e) { System.out.println("轮询线程被中断,正在退出..."); Thread.currentThread().interrupt(); break; } catch (Exception e) { System.err.println("轮询过程中发生错误: " + e.getMessage()); // 记录异常但继续运行,避免因单次异常导致整个监控停止 e.printStackTrace(); // 发生异常时短暂等待后再继续,避免频繁错误循环 try { Thread.sleep(5000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); break; } } } isRunning = false; // System.out.println("轮询任务执行结束"); } /** * 输出所有卡槽状态信息 */ 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 void printAllSlotsStatus() { Fkj[] slots = SlotManager.getSlotArray(); if (slots == null || slots.length == 0) { // System.out.println("无卡槽数据"); return; } // 使用StringBuilder减少字符串拼接开销 StringBuilder statusBuilder = new StringBuilder(); int validSlotCount = 0; for (Fkj slot : slots) { if (slot != null) { validSlotCount++; // 使用下面的推给服务器卡的状态 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 safeGetValue(String value) { return value != null ? value : NULL_VALUE; } /** * 格式化有卡状态 */ private String formatHasCard(String hasCard) { if ("1".equals(hasCard)) return "有卡"; if ("0".equals(hasCard)) return "无卡"; if ("-1".equals(hasCard)) return "未知"; return hasCard; } /** * 格式化有卡状态 */ private String formatHasCard(String hasCard) { if ("1".equals(hasCard)) return "有卡"; if ("0".equals(hasCard)) return "无卡"; if ("-1".equals(hasCard)) return UNKNOWN; 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 formatWorkStatus(String status) { switch (status) { case STATUS_INVALID: return "无效"; case STATUS_STANDBY: return "待机"; case STATUS_CHARGING: return "充电中"; case STATUS_FULL: return "已充满"; case STATUS_FAULT: return "故障"; case STATUS_AUTH_EXPIRED: return "授权到期"; case STATUS_TIMEOUT: return "通信超时"; case STATUS_UNKNOWN: return UNKNOWN; default: return status; } } /** * 格式化故障状态 */ private String formatFault(String fault) { switch (fault) { case "0": return "正常"; case "1": return "插卡错误"; case "2": return "过流"; case "3": return "门控故障"; case "4": return "过压"; case "5": return "欠压"; case "-1": return "未知"; default: return fault; } } } /** * 格式化故障状态 */ private String formatFault(String fault) { switch (fault) { case FAULT_NORMAL: return NORMAL; case FAULT_CARD_ERROR: return "插卡错误"; case FAULT_OVER_CURRENT: return "过流"; case FAULT_DOOR_FAULT: return "门控故障"; case FAULT_OVER_VOLTAGE: return "过压"; case FAULT_UNDER_VOLTAGE: return "欠压"; case FAULT_UNKNOWN: return UNKNOWN; default: return fault; } } } /** * 设置轮询间隔(单位:毫秒) * @param interval 间隔时间,毫秒 */ public static void setPollInterval(int interval) { // 注意:这个设置不会立即生效,需要重启轮询线程 System.out.println("新的轮询间隔将在下次启动时生效: " + interval + "ms"); } /** * 设置轮询间隔(单位:毫秒) * @param interval 间隔时间,毫秒 */ public static void setPollInterval(int interval) { if (interval <= 0) { throw new IllegalArgumentException("轮询间隔必须大于0"); } pollInterval = interval; System.out.println("轮询间隔已更新: " + interval + "ms"); } /** * 获取当前轮询间隔 * @return 轮询间隔(毫秒) */ public static int getPollInterval() { return POLL_INTERVAL; } /** * 获取当前轮询间隔 * @return 轮询间隔(毫秒) */ public static int getPollInterval() { return pollInterval; } /** * 手动触发一次状态输出(不等待间隔) */ public static void triggerManualOutput() { if (isRunning) { new PollingTask().printAllSlotsStatus(); } else { System.out.println("轮询线程未运行,无法手动触发输出"); } } /** * 手动触发一次状态输出(不等待间隔) */ public static void triggerManualOutput() { if (isRunning && pollThread != null) { new PollingTask().printAllSlotsStatus(); } else { System.out.println("轮询线程未运行,无法手动触发输出"); } } /** * 安全关闭所有资源 */ public static void shutdown() { stopPolling(); } }