package chuankou; import java.text.SimpleDateFormat; import java.util.Date; import javax.swing.SwingWorker; import chushihua.lunxun; import dialog.Charulog; import dialog.Dingshidialog; import dialog.Errlog; import publicway.OpenDoor; import xitongshezhi.SystemDebugDialog; /** * 串口消息发送工具类 * 提供高性能的串口消息发送功能,适合高频调用 */ public class Sendmsg { // 静态串口服务实例 private static volatile SerialPortService serialService = null; private static volatile boolean isPortOpen = false; // 改为非final,支持动态控制 private static boolean DEBUG_MODE = false; // 日期格式化 private static final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SSS"); /**发卡服务器控制打开某个柜门调用指令 * @param int slotId柜门编号1-60 * @param int type 1是服务器发卡,2是管理员发卡*/ public static boolean opendoorzhiling(int slotId,int type) { lunxun.setSendChaxunzhiling(false);//暂停查询指令 // 调用OpenDoor生成开门指令 String command = OpenDoor.openOneDoor(slotId, type); boolean sendResult = Sendmsg.sendMessage(command); String mes=command+";type"+type+"控制打开"+slotId+"柜门"; Charulog.logOperation(mes); if (lunxun.DEBUG_ENABLED) { SystemDebugDialog.appendAsciiData(mes); } lunxun.setSendChaxunzhiling(true);//开始查询指令 return sendResult; } /** * 打开全部卡槽的公用静态方法 * @param type 操作类型:1-服务器发卡,2-管理员发卡 */ public static void openAllSlots(int type) { lunxun.setSendChaxunzhiling(false);//暂停查询指令 // 使用SwingWorker在后台执行,避免阻塞UI SwingWorker worker = new SwingWorker() { @Override protected Void doInBackground() throws Exception { // 遍历所有卡槽(1-60) for (int slotId = 1; slotId <= 60; slotId++) { try { // 生成开门指令 String command = OpenDoor.openOneDoor(slotId, type); // 发送串口指令 boolean sent = Sendmsg.sendMessage(command); if (!sent) { Errlog.logOperation("发送指令到卡槽 " + slotId + " 失败"); } // 间隔100ms Thread.sleep(100); } catch (Exception e) { Errlog.logOperation("处理卡槽 " + slotId + " 时发生错误: " + e.getMessage()); e.printStackTrace(); } } return null; } @Override protected void done() { // 可选:完成后可以添加回调处理 System.out.println("全部卡槽开门指令发送完成"); String types="管理员"; if(type==1) { types="服务器指令"; } String message=types+"已将全部卡槽已经打开请取卡"; Dingshidialog.showTimedDialog(null,5,message); Charulog.logOperation(message); } }; worker.execute(); lunxun.setSendChaxunzhiling(true);//开始查询指令 } /** * 设置串口服务实例 * @param service 串口服务实例 * @param open 串口是否打开 */ public static void setSerialService(SerialPortService service, boolean open) { serialService = service; isPortOpen = open; } /** * 获取串口服务实例 */ public static SerialPortService getSerialService() { return serialService; } /** * 发送消息到串口(带重试机制) */ public static boolean sendMessage(String message) { if (!isPortOpen || serialService == null) { Errlog.logOperation("[" + getCurrentTime() + "] 串口未打开,无法发送数据"); return false; } if (message == null || message.trim().isEmpty()) { Errlog.logOperation("[" + getCurrentTime() + "] 发送数据为空"); return false; } String text = message.trim(); int retryCount = 0; final int MAX_RETRY = 2; while (retryCount <= MAX_RETRY) { try { byte[] data = hexStringToByteArray(text); if (data == null) { Errlog.logOperation("[" + getCurrentTime() + "] HEX转换失败,数据: " + text); return false; } boolean sendResult = serialService.send(data); if (sendResult) { if (DEBUG_MODE) { System.out.println("[" + getCurrentTime() + "] 发送成功: " + text.toUpperCase()); } return true; } else { retryCount++; if (retryCount <= MAX_RETRY) { Errlog.logOperation("[" + getCurrentTime() + "] 发送失败,正在重试 (" + retryCount + "/" + MAX_RETRY + ")"); try { Thread.sleep(50); // 重试前等待 } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } else { Errlog.logOperation("[" + getCurrentTime() + "] 串口发送失败,指令: " + text.toUpperCase()); Errlog.logOperation("[" + getCurrentTime() + "] 串口状态 - 打开: " + isPortOpen + ", 服务: " + (serialService != null)); if (serialService != null) { Errlog.logOperation("[" + getCurrentTime() + "] 串口服务状态 - 是否打开: " + serialService.isOpen()); } return false; } } } catch (Exception e) { Errlog.logOperation("[" + getCurrentTime() + "] 发送异常,指令: " + text.toUpperCase()); e.printStackTrace(); return false; } } return false; } /** * 检查串口是否已打开 * @return 串口打开状态 */ public static boolean isPortOpen() { boolean open = isPortOpen && serialService != null; if (!open && DEBUG_MODE) { Errlog.logOperation("[" + getCurrentTime() + "] 串口状态检查: 未打开"); } return open; } /** * HEX字符串转字节数组 * @param s HEX字符串 * @return 字节数组 */ private static byte[] hexStringToByteArray(String s) { if (s == null || s.isEmpty()) { return new byte[0]; } s = s.replaceAll("\\s+", ""); // 移除空格 int len = s.length(); if (len % 2 != 0) { throw new IllegalArgumentException("HEX字符串长度必须为偶数,当前长度: " + len + ", 数据: " + s); } byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { int high = Character.digit(s.charAt(i), 16); int low = Character.digit(s.charAt(i + 1), 16); if (high == -1 || low == -1) { throw new IllegalArgumentException("无效的HEX字符: '" + s.charAt(i) + s.charAt(i + 1) + "' 在位置 " + i + "-" + (i+1) + ", 完整数据: " + s); } data[i / 2] = (byte) ((high << 4) + low); } return data; } /** * 字节数组转HEX字符串 * @param bytes 字节数组 * @return HEX字符串 */ public static String bytesToHex(byte[] bytes) { if (bytes == null || bytes.length == 0) { return ""; } StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02x", b)); } return sb.toString(); } /** * 获取当前时间字符串 * @return 时间字符串 */ private static String getCurrentTime() { return timeFormat.format(new Date()); } /** * 启用调试模式 */ public static void enableDebugMode() { DEBUG_MODE = true; System.out.println("[" + getCurrentTime() + "] Sendmsg调试模式已启用"); } /** * 禁用调试模式 */ public static void disableDebugMode() { DEBUG_MODE = false; System.out.println("[" + getCurrentTime() + "] Sendmsg调试模式已禁用"); } /** * 设置调试模式 */ public static void setDebugMode(boolean debug) { DEBUG_MODE = debug; System.out.println("[" + getCurrentTime() + "] Sendmsg调试模式: " + (debug ? "启用" : "禁用")); } }