张世豪
21 小时以前 03b0fb0ba2de86bcfff277778826547c0e37a93f
优化修改
已修改14个文件
1774 ■■■■ 文件已修改
bin/chuankou/Sendmsg.class 补丁 | 查看 | 原始文档 | blame | 历史
bin/chuankou/SerialPortService.class 补丁 | 查看 | 原始文档 | blame | 历史
bin/chushihua/lunxun$PollingTask.class 补丁 | 查看 | 原始文档 | blame | 历史
bin/chushihua/lunxun.class 补丁 | 查看 | 原始文档 | blame | 历史
bin/home/Homein.class 补丁 | 查看 | 原始文档 | blame | 历史
bin/xitongshezhi/canshushezhi$1.class 补丁 | 查看 | 原始文档 | blame | 历史
bin/xitongshezhi/canshushezhi$2.class 补丁 | 查看 | 原始文档 | blame | 历史
bin/xitongshezhi/canshushezhi.class 补丁 | 查看 | 原始文档 | blame | 历史
src/chuankou/Sendmsg.java 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/chuankou/SerialPortService.java 439 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/chushihua/lunxun.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/chushihua/lunxunzaixian.java 966 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/home/Homein.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/xitongshezhi/canshushezhi.java 236 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
bin/chuankou/Sendmsg.class
Binary files differ
bin/chuankou/SerialPortService.class
Binary files differ
bin/chushihua/lunxun$PollingTask.class
Binary files differ
bin/chushihua/lunxun.class
Binary files differ
bin/home/Homein.class
Binary files differ
bin/xitongshezhi/canshushezhi$1.class
Binary files differ
bin/xitongshezhi/canshushezhi$2.class
Binary files differ
bin/xitongshezhi/canshushezhi.class
Binary files differ
src/chuankou/Sendmsg.java
@@ -11,8 +11,8 @@
    private static volatile SerialPortService serialService = null;
    private static volatile boolean isPortOpen = false;
    
    // 调试模式开关
    private static final boolean DEBUG_MODE = false;
    // 改为非final,支持动态控制
    private static boolean DEBUG_MODE = false;
    
    // 日期格式化
    private static final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SSS");
@@ -35,48 +35,65 @@
    }
    
    /**
     * 发送消息到串口
     * @param message 要发送的HEX格式消息
     * @return 发送成功返回true,失败返回false
     * 发送消息到串口(带重试机制)
     */
    public static boolean sendMessage(String message) {
        if (!isPortOpen || serialService == null) {
            if (DEBUG_MODE) {
                System.err.println("[" + getCurrentTime() + "] 串口未打开,无法发送数据");
            }
            System.err.println("[" + getCurrentTime() + "] 串口未打开,无法发送数据");
            return false;
        }
        
        if (message == null || message.trim().isEmpty()) {
            if (DEBUG_MODE) {
                System.err.println("[" + getCurrentTime() + "] 发送数据为空");
            }
            System.err.println("[" + getCurrentTime() + "] 发送数据为空");
            return false;
        }
        
        String text = message.trim();
        int retryCount = 0;
        final int MAX_RETRY = 2;
        
        try {
            // HEX格式发送
            byte[] data = hexStringToByteArray(text);
            if (data != null && serialService.send(data)) {
                // 高频调用时避免频繁的日志输出,只在调试时记录
                if (DEBUG_MODE) {
                    System.out.println("[" + getCurrentTime() + "] 发送: " + text.toUpperCase());
        while (retryCount <= MAX_RETRY) {
            try {
                byte[] data = hexStringToByteArray(text);
                if (data == null) {
                    System.err.println("[" + getCurrentTime() + "] HEX转换失败,数据: " + text);
                    return false;
                }
                return true;
            } else {
                if (DEBUG_MODE) {
                    System.err.println("[" + getCurrentTime() + "] 数据发送失败");
                boolean sendResult = serialService.send(data);
                if (sendResult) {
                    if (DEBUG_MODE) {
                        System.out.println("[" + getCurrentTime() + "] 发送成功: " + text.toUpperCase());
                    }
                    return true;
                } else {
                    retryCount++;
                    if (retryCount <= MAX_RETRY) {
                        System.err.println("[" + getCurrentTime() + "] 发送失败,正在重试 (" + retryCount + "/" + MAX_RETRY + ")");
                        try {
                            Thread.sleep(50); // 重试前等待
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            break;
                        }
                    } else {
                        System.err.println("[" + getCurrentTime() + "] 串口发送失败,指令: " + text.toUpperCase());
                        System.err.println("[" + getCurrentTime() + "] 串口状态 - 打开: " + isPortOpen + ", 服务: " + (serialService != null));
                        if (serialService != null) {
                            System.err.println("[" + getCurrentTime() + "] 串口服务状态 - 是否打开: " + serialService.isOpen());
                        }
                        return false;
                    }
                }
            } catch (Exception e) {
                System.err.println("[" + getCurrentTime() + "] 发送异常,指令: " + text.toUpperCase());
                e.printStackTrace();
                return false;
            }
        } catch (Exception e) {
            if (DEBUG_MODE) {
                System.err.println("[" + getCurrentTime() + "] 数据格式错误: " + e.getMessage());
            }
            return false;
        }
        return false;
    }
    
    /**
@@ -84,7 +101,11 @@
     * @return 串口打开状态
     */
    public static boolean isPortOpen() {
        return isPortOpen && serialService != null;
        boolean open = isPortOpen && serialService != null;
        if (!open && DEBUG_MODE) {
            System.err.println("[" + getCurrentTime() + "] 串口状态检查: 未打开");
        }
        return open;
    }
    
    /**
@@ -100,7 +121,7 @@
        s = s.replaceAll("\\s+", ""); // 移除空格
        int len = s.length();
        if (len % 2 != 0) {
            throw new IllegalArgumentException("HEX字符串长度必须为偶数");
            throw new IllegalArgumentException("HEX字符串长度必须为偶数,当前长度: " + len + ", 数据: " + s);
        }
        
        byte[] data = new byte[len / 2];
@@ -109,7 +130,7 @@
            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));
                throw new IllegalArgumentException("无效的HEX字符: '" + s.charAt(i) + s.charAt(i + 1) + "' 在位置 " + i + "-" + (i+1) + ", 完整数据: " + s);
            }
            
            data[i / 2] = (byte) ((high << 4) + low);
@@ -144,12 +165,25 @@
    
    /**
     * 启用调试模式
     * 注意:这会修改静态final变量,实际项目中不建议这样做
     * 这里只是演示,实际应该通过配置文件控制
     */
    public static void enableDebugMode() {
        // 在实际项目中,应该使用可配置的方式而不是修改final变量
        // 这里只是示意,实际使用时需要重新设计
        System.out.println("调试模式已启用");
        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 ? "启用" : "禁用"));
    }
}
src/chuankou/SerialPortService.java
@@ -10,234 +10,249 @@
public class SerialPortService {
    private SerialPort port;
    private volatile boolean capturing = false;
    private volatile boolean paused = true;
    private Thread readerThread;
    private Consumer<byte[]> responseConsumer;
    // 优化:重用缓冲区,减少内存分配
    private byte[] readBuffer = new byte[200];
    private ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
    private Consumer<byte[]> dataReceivedCallback;
    // 新增:协议解析器引用
    private SerialProtocolParser protocolParser = new SerialProtocolParser();
    // 新增:数据条数计数器
    public static  int receivedDataCount = 0;
    private SerialPort port;
    private volatile boolean capturing = false;
    private volatile boolean paused = true;
    private Thread readerThread;
    private Consumer<byte[]> responseConsumer;
    // 其他现有方法保持不变...
    /**
     * 获取串口接收的数据条数
     * 当条数超过1万时自动从1开始重新计数
     * @return 数据条数字符串
     */
    public static String getReceivedDataCount() {
        receivedDataCount++;
        if (receivedDataCount > 10000) {
            receivedDataCount = 1;
        }
        return String.valueOf(receivedDataCount);
    }
    public static void setReceivedDataCount(int receivedDataCount) {
        SerialPortService.receivedDataCount = receivedDataCount;
    }
    /**
     * 获取协议解析器实例
     */
    public SerialProtocolParser getProtocolParser() {
        return protocolParser;
    }
    // 优化:重用缓冲区,减少内存分配
    private byte[] readBuffer = new byte[200];
    private ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
    private Consumer<byte[]> dataReceivedCallback;
    // 新增:协议解析器引用
    private SerialProtocolParser protocolParser = new SerialProtocolParser();
    // 新增:数据条数计数器
    public static  int receivedDataCount = 0;
    // 其他现有方法保持不变...
    /**
     * 重置数据条数计数器
     */
    public void resetReceivedDataCount() {
        receivedDataCount = 0;
    }
     * 获取串口接收的数据条数
     * 当条数超过1万时自动从1开始重新计数
     * @return 数据条数字符串
     */
    public static String getReceivedDataCount() {
        receivedDataCount++;
        if (receivedDataCount > 10000) {
            receivedDataCount = 1;
        }
        return String.valueOf(receivedDataCount);
    }
    // 以下为原有代码,保持不变...
    public InputStream getInputStream() {
        if (port != null && port.isOpen()) {
            return port.getInputStream();
        }
        return null;
    }
    public static void setReceivedDataCount(int receivedDataCount) {
        SerialPortService.receivedDataCount = receivedDataCount;
    }
    public OutputStream getOutputStream() {
        if (port != null && port.isOpen()) {
            return port.getOutputStream();
        }
        return null;
    }
    public void setComPortTimeouts(int timeoutMode, int readTimeout, int writeTimeout) {
        if (port != null && port.isOpen()) {
            port.setComPortTimeouts(timeoutMode, readTimeout, writeTimeout);
        }
    }
    /**
     * 设置协议解析器
     */
    public void setProtocolParser(SerialProtocolParser parser) {
        this.protocolParser = parser;
    }
    /**
     * 启用调试输出,将接收到的数据打印到控制台
     */
    public void enableDebugOutput() {
        //System.out.println("串口调试输出已启用 - 开始监听串口数据...");
    }
    /**
     * 获取协议解析器实例
     */
    public SerialProtocolParser getProtocolParser() {
        return protocolParser;
    }
    /**
     * 获取当前调试状态
     */
    public boolean isDebugEnabled() {
        return capturing;
    }
    public void startCapture() {
        if (dataReceivedCallback != null) {
            startCapture(dataReceivedCallback);
        } else {
            System.err.println("No data received callback set. Please call startCapture(Consumer<byte[]> onReceived) first.");
        }
   }
    /**
     * 重置数据条数计数器
     */
    public void resetReceivedDataCount() {
        receivedDataCount = 0;
    }
    /**
     * 打开串口
     */
    public boolean open(String portName, int baud) {
        if (port != null && port.isOpen()) {
            return true;
        }
    // 以下为原有代码,保持不变...
    public InputStream getInputStream() {
        if (port != null && port.isOpen()) {
            return port.getInputStream();
        }
        return null;
    }
        port = SerialPort.getCommPort(portName);
        port.setComPortParameters(baud, 8, 1, SerialPort.NO_PARITY);
        port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 1, 0);
        protocolParser.start();
        return port.openPort();
    }
    public void setResponseConsumer(Consumer<byte[]> consumer) {
        this.responseConsumer = consumer;
    }
    public OutputStream getOutputStream() {
        if (port != null && port.isOpen()) {
            return port.getOutputStream();
        }
        return null;
    }
    /**
     * 关闭串口
     */
    public void close() {
        stopCapture();
        if (port != null && port.isOpen()) {
            port.closePort();
        }
        port = null;
    }
    public void setComPortTimeouts(int timeoutMode, int readTimeout, int writeTimeout) {
        if (port != null && port.isOpen()) {
            port.setComPortTimeouts(timeoutMode, readTimeout, writeTimeout);
        }
    }
    /**
     * 启动数据接收线程
     */
    public void startCapture(Consumer<byte[]> onReceived) {
        this.dataReceivedCallback = onReceived;
        if (capturing || port == null || !port.isOpen()) return;
        capturing = true;
        paused = false;
    /**
     * 设置协议解析器
     */
    public void setProtocolParser(SerialProtocolParser parser) {
        this.protocolParser = parser;
    }
        readerThread = new Thread(() -> {
            buffer.reset();
            long lastReceivedTime = 0;
            while (capturing && port.isOpen()) {
                long currentTime = System.currentTimeMillis();
                if (buffer.size() > 0 && (currentTime - lastReceivedTime) >= 20) {
                    byte[] data = buffer.toByteArray();
                    SystemDebugDialog.appendHexData(data);
                    // 新增:将数据传递给协议解析器
                    if (protocolParser != null) {
                        protocolParser.receiveData(data);
                    }
                    if (!paused) {
                        onReceived.accept(data);
                        if (responseConsumer != null) {
                            responseConsumer.accept(data);
                        }
                    }
                    buffer.reset();
                }
    /**
     * 启用调试输出,将接收到的数据打印到控制台
     */
    public void enableDebugOutput() {
        //System.out.println("串口调试输出已启用 - 开始监听串口数据...");
    }
                int len = port.readBytes(readBuffer, readBuffer.length);
                currentTime = System.currentTimeMillis();
    /**
     * 获取当前调试状态
     */
    public boolean isDebugEnabled() {
        return capturing;
    }
                if (len > 0) {
                    buffer.write(readBuffer, 0, len);
                    lastReceivedTime = currentTime;
                }
                if (len <= 0 && buffer.size() == 0) {
                    try { Thread.sleep(1); } catch (InterruptedException ignore) {}
                }
            }
            if (buffer.size() > 0) {
                byte[] data = buffer.toByteArray();
                SystemDebugDialog.appendHexData(data);
                // 新增:将数据传递给协议解析器
                if (protocolParser != null) {
                    protocolParser.receiveData(data);
                }
                if (!paused) {
                    onReceived.accept(data);
                    if (responseConsumer != null) {
                        responseConsumer.accept(data);
                    }
                }
            }
        });
        readerThread.setDaemon(true);
        readerThread.start();
    }
    public void startCapture() {
        if (dataReceivedCallback != null) {
            startCapture(dataReceivedCallback);
        } else {
            System.err.println("No data received callback set. Please call startCapture(Consumer<byte[]> onReceived) first.");
        }
    }
    /**
     * 停止数据接收线程
     */
    public void stopCapture() {
        capturing = false;
        if (readerThread != null) {
            try { readerThread.join(500); } catch (InterruptedException ignore) {}
            readerThread = null;
        }
    }
    /**
     * 打开串口
     */
    public boolean open(String portName, int baud) {
        if (port != null && port.isOpen()) {
            return true;
        }
    public void setPaused(boolean paused) {
        this.paused = paused;
    }
        port = SerialPort.getCommPort(portName);
        port.setComPortParameters(baud, 8, 1, SerialPort.NO_PARITY);
        port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 1, 0);
        protocolParser.start();
        return port.openPort();
    }
    public boolean isPaused() {
        return paused;
    }
    public void setResponseConsumer(Consumer<byte[]> consumer) {
        this.responseConsumer = consumer;
    }
    public boolean isOpen() {
        return port != null && port.isOpen();
    }
    /**
     * 关闭串口
     */
    public void close() {
        stopCapture();
        if (port != null && port.isOpen()) {
            port.closePort();
        }
        port = null;
    }
    /**
     * 发送数据
     */
    public boolean send(byte[] data) {
        if (!isOpen()) {
            return false;
        }
        return port != null && port.isOpen() && port.writeBytes(data, data.length) > 0;
    }
    /**
     * 启动数据接收线程
     */
    public void startCapture(Consumer<byte[]> onReceived) {
        this.dataReceivedCallback = onReceived;
        if (capturing || port == null || !port.isOpen()) return;
        capturing = true;
        paused = false;
        readerThread = new Thread(() -> {
            buffer.reset();
            long lastReceivedTime = 0;
            while (capturing && port.isOpen()) {
                long currentTime = System.currentTimeMillis();
                if (buffer.size() > 0 && (currentTime - lastReceivedTime) >= 20) {
                    byte[] data = buffer.toByteArray();
                    SystemDebugDialog.appendHexData(data);
                    // 新增:将数据传递给协议解析器
                    if (protocolParser != null) {
                        protocolParser.receiveData(data);
                    }
                    if (!paused) {
                        onReceived.accept(data);
                        if (responseConsumer != null) {
                            responseConsumer.accept(data);
                        }
                    }
                    buffer.reset();
                }
                int len = port.readBytes(readBuffer, readBuffer.length);
                currentTime = System.currentTimeMillis();
                if (len > 0) {
                    buffer.write(readBuffer, 0, len);
                    lastReceivedTime = currentTime;
                }
                if (len <= 0 && buffer.size() == 0) {
                    try { Thread.sleep(1); } catch (InterruptedException ignore) {}
                }
            }
            if (buffer.size() > 0) {
                byte[] data = buffer.toByteArray();
                SystemDebugDialog.appendHexData(data);
                // 新增:将数据传递给协议解析器
                if (protocolParser != null) {
                    protocolParser.receiveData(data);
                }
                if (!paused) {
                    onReceived.accept(data);
                    if (responseConsumer != null) {
                        responseConsumer.accept(data);
                    }
                }
            }
        });
        readerThread.setDaemon(true);
        readerThread.start();
    }
    /**
     * 停止数据接收线程
     */
    public void stopCapture() {
        capturing = false;
        if (readerThread != null) {
            try { readerThread.join(500); } catch (InterruptedException ignore) {}
            readerThread = null;
        }
    }
    public void setPaused(boolean paused) {
        this.paused = paused;
    }
    public boolean isPaused() {
        return paused;
    }
    public boolean isOpen() {
        return port != null && port.isOpen();
    }
    /**
     * 发送数据(优化版本)
     */
    public boolean send(byte[] data) {
        if (!isOpen()) {
            return false;
        }
        // 添加发送前的串口状态检查
        if (port == null || !port.isOpen()) {
            return false;
        }
        try {
            // 添加小延迟,避免连续发送
            Thread.sleep(2);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
        int result = port.writeBytes(data, data.length);
        return result > 0;
    }
}
src/chushihua/lunxun.java
@@ -115,10 +115,7 @@
        try {
            pollingThread = new Thread(new PollingTask(), "CardSlot-Polling-Thread");
            pollingThread.setDaemon(true);
            pollingThread.start();
            if (DEBUG_ENABLED) {
                //System.out.println("轮询查询已启动,间隔: " + pollingInterval + "ms");
            }
            pollingThread.start();
            return true;
        } catch (Exception e) {
            System.err.println("启动轮询查询线程时发生异常: " + e.getMessage());
@@ -387,7 +384,7 @@
                                } else {
                                    consecutiveFailures++;
                                    if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
                                        System.err.println("连续失败次数过多,暂停轮询");
                                        System.err.println("lunxun连续失败次数过多,暂停轮询");
                                        pausePolling();
                                        break;
                                    }
@@ -442,7 +439,7 @@
                    if (sendResult) {
                        // 只在调试时输出,避免频繁打印
                        if (DEBUG_ENABLED) {
                            SystemDebugDialog.appendAsciiData(String.format("Slot %d Send query (hasCard !=1)", slotNumber));
                            SystemDebugDialog.appendAsciiData(String.format("Slot %d Send query (hasCard !=1)\n", slotNumber));
                        }
                        return true;
                    } else {
src/chushihua/lunxunzaixian.java
@@ -13,480 +13,494 @@
 * 与原有的轮询查询类互补,专注于在线设备的持续监控
 */
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;
        }
        // 检查串口连接状态
        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;
        }
        // 恢复前检查串口连接
        if (!checkSerialConnectionWithRetry()) {
            System.err.println("串口未连接,无法恢复在线轮询");
            return false;
        }
        isPaused.set(false);
        synchronized (lunxunzaixian.class) {
            lunxunzaixian.class.notifyAll(); // 唤醒等待的线程
        }
        //System.out.println("在线轮询已恢复");
        return true;
    }
    /**
     * 检查在线轮询状态
     * @return true-正在运行, 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");
        // 如果正在运行,重新启动以应用新的间隔
        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;
                    }
                    // 检查串口连接状态
                    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);
    }
    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 = 120000; // 完整轮询周期间隔:60秒
    private static int slotInterval = 200;    // 卡槽间查询间隔:500毫秒
    // 卡槽相关常量
    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;
        }
        // 检查串口连接状态
        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;
        }
        // 恢复前检查串口连接
        if (!checkSerialConnectionWithRetry()) {
            System.err.println("串口未连接,无法恢复在线轮询");
            return false;
        }
        isPaused.set(false);
        synchronized (lunxunzaixian.class) {
            lunxunzaixian.class.notifyAll(); // 唤醒等待的线程
        }
        //System.out.println("在线轮询已恢复");
        return true;
    }
    /**
     * 检查在线轮询状态
     * @return true-正在运行, 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");
        // 如果正在运行,重新启动以应用新的间隔
        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;
                    }
                    // 检查串口连接状态
                    if (!checkSerialConnectionWithRetry()) {
                        System.err.println("串口连接断开,暂停在线轮询");
                        pauseOnlinePolling();
                        continue;
                    }
                    // 执行一轮有卡卡槽的轮询
                    if (pollCardSlotsOptimized()) {
                        consecutiveFailures = 0; // 重置连续失败计数
                    } else {
                        consecutiveFailures++;
                        if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
                            System.err.println("lunxunzaixian连续失败次数过多,暂停在线轮询");
                            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 j = 0; j < batch.size(); j++) {
                    int slotNumber = batch.get(j);
                    if (sendQueryToCardSlot(slotNumber)) {
                        polledCount++;
                    }
                    // 重要修复:每个卡槽查询后等待指定间隔(最后一个卡槽除外)
                    if (j < batch.size() - 1) {
                        try {
                            Thread.sleep(slotInterval); // 卡槽间间隔
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            break;
                        }
                    }
                }
                // 批次间间隔(保持原有逻辑)
                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);
    }
}
src/home/Homein.java
@@ -129,21 +129,13 @@
            
            if (serialConnected) {
                // 4. 串口连接成功后,启动轮询
                boolean pollingStarted = startPollingService();
                startPollingService();
                showMainInterface();
                //启动轮询卡状态给服务器发数据
                lunxunkazhuangtai.startPolling();
                //启动在线的卡状态轮询
                lunxunzaixian.startOnlinePolling();
                
                if (pollingStarted) {
                    showMainInterface();
                    //启动轮询卡状态给服务器发数据
                    lunxunkazhuangtai.startPolling();
                    //启动在线的卡状态轮询
                    lunxunzaixian.startOnlinePolling();
                } else {
                    System.err.println("轮询服务启动失败");
                    JOptionPane.showMessageDialog(null,
                        "轮询服务启动失败,应用程序无法正常运行",
                        "警告",
                        JOptionPane.WARNING_MESSAGE);
                }
            } else {
                System.err.println("串口连接失败");
                // 串口连接失败已经由SerialPortConnectionDialog处理,直接退出
src/xitongshezhi/canshushezhi.java
@@ -17,12 +17,14 @@
    private static final int SCREEN_WIDTH = 600;
    private static final int SCREEN_HEIGHT = 1024;
    
    // 颜色常量 - 使用不透明颜色
    // 颜色定义 - 使用mimaguanli.java中的颜色方案
    private static final Color BACKGROUND_COLOR = new Color(15, 28, 48);
    private static final Color CARD_COLOR = new Color(26, 43, 68);
    private static final Color PRIMARY_COLOR = new Color(52, 152, 219);
    private static final Color SECONDARY_COLOR = new Color(46, 204, 113);
    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 static final Color FIELD_BACKGROUND = new Color(240, 240, 240);
    
    // UI组件
    private JPanel mainPanel;
@@ -58,10 +60,10 @@
            e.printStackTrace();
        }
        
        // 创建主面板 - 不透明背景
        // 创建主面板 - 使用mimaguanli的背景色
        mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());
        mainPanel.setBackground(DARK_COLOR);
        mainPanel.setBackground(BACKGROUND_COLOR);
        mainPanel.setOpaque(true);
        mainPanel.setBorder(new EmptyBorder(12, 12, 12, 12));
        
@@ -82,14 +84,18 @@
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 22));
        titleLabel.setForeground(TEXT_COLOR);
        
        // 关闭按钮
        // 关闭按钮 - 使用mimaguanli的按钮样式
        JButton 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.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createLineBorder(new Color(40, 120, 180), 1),
            BorderFactory.createEmptyBorder(8, 16, 8, 16)
        ));
        backButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
        backButton.addActionListener(e -> dispose());
        
        // 关闭按钮悬停效果
@@ -130,12 +136,14 @@
        scrollPane.setOpaque(false);
        scrollPane.getViewport().setOpaque(false);
        
        // 基本参数设置卡片
        settingsPanel.add(createBasicSettingsCard());
        settingsPanel.add(Box.createRigidArea(new Dimension(0, 12)));
        // 自定义滚动条
        JScrollBar verticalScrollBar = scrollPane.getVerticalScrollBar();
        verticalScrollBar.setBackground(CARD_COLOR);
        verticalScrollBar.setForeground(PRIMARY_COLOR);
        verticalScrollBar.setUnitIncrement(20);
        
        // 设备参数设置卡片
        settingsPanel.add(createDeviceSettingsCard());
        // 合并的参数设置卡片
        settingsPanel.add(createMergedSettingsCard());
        settingsPanel.add(Box.createRigidArea(new Dimension(0, 12)));
        
        // 保存按钮
@@ -148,172 +156,148 @@
        return container;
    }
    
    private JPanel createBasicSettingsCard() {
    private JPanel createMergedSettingsCard() {
        JPanel card = new JPanel();
        card.setLayout(new BorderLayout());
        card.setBackground(DARK_LIGHT_COLOR);
        card.setBackground(CARD_COLOR);
        card.setOpaque(true);
        card.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createLineBorder(new Color(52, 152, 219, 128)),
            BorderFactory.createEmptyBorder(15, 15, 15, 15)
            BorderFactory.createLineBorder(new Color(52, 152, 219, 100), 1),
            BorderFactory.createEmptyBorder(20, 20, 20, 20)
        ));
        
        // 卡头
        JPanel cardHeader = new JPanel(new BorderLayout());
        cardHeader.setOpaque(false);
        JLabel titleLabel = new JLabel("基本参数设置");
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 16));
        titleLabel.setForeground(TEXT_COLOR);
        cardHeader.add(titleLabel, BorderLayout.WEST);
        card.add(cardHeader, BorderLayout.NORTH);
        // 表单内容 - 使用网格布局实现标签在左,文本框在右
        // 调整行高为80像素,为60像素高的组件提供足够的间距
        JPanel formPanel = new JPanel(new GridLayout(3, 2, 10, 20));
        // 表单内容 - 使用水平布局实现标签在左,文本框在右
        JPanel formPanel = new JPanel();
        formPanel.setLayout(new BoxLayout(formPanel, BoxLayout.Y_AXIS));
        formPanel.setOpaque(false);
        formPanel.setBorder(new EmptyBorder(15, 0, 0, 0));
        
        // 发卡机编号
        JLabel deviceIdLabel = new JLabel("发卡机编号:");
        deviceIdLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 13));
        deviceIdLabel.setForeground(TEXT_COLOR);
        formPanel.add(deviceIdLabel);
        deviceIdField = new JTextField();
        styleFormField(deviceIdField);
        formPanel.add(deviceIdField);
        formPanel.add(createHorizontalField("发卡机编号:", deviceIdField = new JTextField()));
        formPanel.add(Box.createRigidArea(new Dimension(0, 18)));
        
        // 服务器地址
        JLabel serverAddressLabel = new JLabel("服务器地址:");
        serverAddressLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 13));
        serverAddressLabel.setForeground(TEXT_COLOR);
        formPanel.add(serverAddressLabel);
        serverAddressField = new JTextField();
        styleFormField(serverAddressField);
        formPanel.add(serverAddressField);
        formPanel.add(createHorizontalField("服务器地址:", serverAddressField = new JTextField()));
        formPanel.add(Box.createRigidArea(new Dimension(0, 18)));
        
        // 服务器端口
        JLabel serverPortLabel = new JLabel("服务器端口:");
        serverPortLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 13));
        serverPortLabel.setForeground(TEXT_COLOR);
        formPanel.add(serverPortLabel);
        formPanel.add(createHorizontalField("服务器端口:", serverPortField = new JTextField()));
        formPanel.add(Box.createRigidArea(new Dimension(0, 18)));
        
        serverPortField = new JTextField();
        styleFormField(serverPortField);
        formPanel.add(serverPortField);
        // 卡槽总数
        formPanel.add(createHorizontalField("卡槽总数:", slotCountField = new JTextField()));
        formPanel.add(Box.createRigidArea(new Dimension(0, 18)));
        // 读卡号模式
        formPanel.add(createHorizontalComboBoxField("读卡号模式:", readModeComboBox = new JComboBox<>(new String[]{"主动模式", "被动模式"})));
        
        card.add(formPanel, BorderLayout.CENTER);
        
        return card;
    }
    
    private JPanel createDeviceSettingsCard() {
        JPanel card = new JPanel();
        card.setLayout(new BorderLayout());
        card.setBackground(DARK_LIGHT_COLOR);
        card.setOpaque(true);
        card.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createLineBorder(new Color(52, 152, 219, 128)),
            BorderFactory.createEmptyBorder(15, 15, 15, 15)
    private JPanel createHorizontalField(String labelText, JTextField textField) {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBackground(CARD_COLOR);
        panel.setMaximumSize(new Dimension(SCREEN_WIDTH - 100, 50));
        // 标签
        JLabel label = new JLabel(labelText);
        label.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
        label.setForeground(TEXT_COLOR);
        label.setPreferredSize(new Dimension(100, 30));
        // 文本框样式 - 使用mimaguanli的样式
        textField.setBackground(FIELD_BACKGROUND);
        textField.setForeground(Color.BLACK);
        textField.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createLineBorder(new Color(200, 200, 200), 1),
            BorderFactory.createEmptyBorder(10, 12, 10, 12)
        ));
        textField.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
        textField.setOpaque(true);
        textField.setPreferredSize(new Dimension(280, 42));
        
        // 卡头
        JPanel cardHeader = new JPanel(new BorderLayout());
        cardHeader.setOpaque(false);
        // 创建水平布局容器
        JPanel horizontalPanel = new JPanel(new BorderLayout());
        horizontalPanel.setBackground(CARD_COLOR);
        horizontalPanel.setMaximumSize(new Dimension(SCREEN_WIDTH - 100, 50));
        
        JLabel titleLabel = new JLabel("设备参数设置");
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 16));
        titleLabel.setForeground(TEXT_COLOR);
        horizontalPanel.add(label, BorderLayout.WEST);
        horizontalPanel.add(textField, BorderLayout.CENTER);
        
        cardHeader.add(titleLabel, BorderLayout.WEST);
        card.add(cardHeader, BorderLayout.NORTH);
        // 添加间距
        horizontalPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
        
        // 表单内容 - 使用网格布局实现标签在左,输入组件在右
        // 调整行高为80像素,为60像素高的组件提供足够的间距
        JPanel formPanel = new JPanel(new GridLayout(2, 2, 10, 20));
        formPanel.setOpaque(false);
        formPanel.setBorder(new EmptyBorder(15, 0, 0, 0));
        return horizontalPanel;
    }
    private JPanel createHorizontalComboBoxField(String labelText, JComboBox<String> comboBox) {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBackground(CARD_COLOR);
        panel.setMaximumSize(new Dimension(SCREEN_WIDTH - 100, 50));
        
        // 卡槽总数
        JLabel slotCountLabel = new JLabel("卡槽总数:");
        slotCountLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 13));
        slotCountLabel.setForeground(TEXT_COLOR);
        formPanel.add(slotCountLabel);
        // 标签
        JLabel label = new JLabel(labelText);
        label.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
        label.setForeground(TEXT_COLOR);
        label.setPreferredSize(new Dimension(100, 30));
        
        slotCountField = new JTextField();
        styleFormField(slotCountField);
        formPanel.add(slotCountField);
        // 组合框样式 - 使用mimaguanli的样式
        comboBox.setBackground(FIELD_BACKGROUND);
        comboBox.setForeground(Color.BLACK);
        comboBox.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createLineBorder(new Color(200, 200, 200), 1),
            BorderFactory.createEmptyBorder(10, 12, 10, 12)
        ));
        comboBox.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
        comboBox.setOpaque(true);
        comboBox.setPreferredSize(new Dimension(280, 42));
        
        // 读卡号模式
        JLabel readModeLabel = new JLabel("读卡号模式:");
        readModeLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 13));
        readModeLabel.setForeground(TEXT_COLOR);
        formPanel.add(readModeLabel);
        // 创建水平布局容器
        JPanel horizontalPanel = new JPanel(new BorderLayout());
        horizontalPanel.setBackground(CARD_COLOR);
        horizontalPanel.setMaximumSize(new Dimension(SCREEN_WIDTH - 100, 50));
        
        readModeComboBox = new JComboBox<>(new String[]{"主动模式", "被动模式"});
        styleComboBox(readModeComboBox);
        formPanel.add(readModeComboBox);
        horizontalPanel.add(label, BorderLayout.WEST);
        horizontalPanel.add(comboBox, BorderLayout.CENTER);
        
        card.add(formPanel, BorderLayout.CENTER);
        // 添加间距
        horizontalPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
        
        return card;
        return horizontalPanel;
    }
    
    private JPanel createSaveButton() {
        JPanel buttonPanel = new JPanel(new BorderLayout());
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        buttonPanel.setOpaque(false);
        buttonPanel.setBorder(new EmptyBorder(10, 0, 0, 0));
        
        JButton saveButton = new JButton("保存所有设置");
        saveButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 16));
        saveButton.setBackground(SECONDARY_COLOR);
        saveButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
        saveButton.setBackground(PRIMARY_COLOR);
        saveButton.setForeground(Color.WHITE);
        saveButton.setOpaque(true);
        saveButton.setFocusPainted(false);
        saveButton.setPreferredSize(new Dimension(0, 60)); // 高度改为60像素
        saveButton.setBorder(BorderFactory.createEmptyBorder(12, 20, 12, 20));
        saveButton.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createLineBorder(new Color(40, 120, 180), 1),
            BorderFactory.createEmptyBorder(8, 16, 8, 16)
        ));
        saveButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
        saveButton.addActionListener(e -> saveSettings());
        
        // 按钮悬停效果
        saveButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                saveButton.setBackground(brighterColor(SECONDARY_COLOR));
                saveButton.setBackground(brighterColor(PRIMARY_COLOR));
            }
            
            public void mouseExited(java.awt.event.MouseEvent evt) {
                saveButton.setBackground(SECONDARY_COLOR);
                saveButton.setBackground(PRIMARY_COLOR);
            }
        });
        
        buttonPanel.add(saveButton, BorderLayout.CENTER);
        buttonPanel.add(saveButton);
        return buttonPanel;
    }
    private void styleFormField(JTextField field) {
        field.setPreferredSize(new Dimension(200, 60)); // 高度改为60像素
        field.setBackground(Color.WHITE); // 不透明白色背景
        field.setForeground(Color.BLACK); // 黑色文字
        field.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createLineBorder(new Color(200, 200, 200)),
            BorderFactory.createEmptyBorder(8, 12, 8, 12)
        ));
        field.setFont(new Font("Microsoft YaHei", Font.PLAIN, 13));
        field.setCaretColor(Color.BLACK);
        field.setOpaque(true); // 确保不透明
    }
    private void styleComboBox(JComboBox<String> comboBox) {
        comboBox.setPreferredSize(new Dimension(200, 60)); // 高度改为60像素
        comboBox.setBackground(Color.WHITE); // 不透明白色背景
        comboBox.setForeground(Color.BLACK); // 黑色文字
        comboBox.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createLineBorder(new Color(200, 200, 200)),
            BorderFactory.createEmptyBorder(8, 12, 8, 12)
        ));
        comboBox.setFont(new Font("Microsoft YaHei", Font.PLAIN, 13));
        comboBox.setOpaque(true); // 确保不透明
    }
    
    private void initializeData() {