张世豪
2025-11-26 2b756769ea4adad21332d8a294871712cd42cc3f
src/chushihua/lunxun.java
@@ -5,6 +5,7 @@
import home.Fkj;
import home.MachineConfig;
import publicway.QueryData;
import publicway.TimestampUtil;
import xitongshezhi.SystemDebugDialog;
import java.util.Iterator;
@@ -24,7 +25,7 @@
   private static volatile boolean isPaused = false;
   private static final AtomicBoolean shouldStop = new AtomicBoolean(false);
   private static Thread pollingThread;
   private static int pollingInterval = 100; // 默认轮询间隔
   private static int pollingInterval =50; // 默认轮询间隔
   public static boolean sendChaxunzhiling=true;//是否向串口发送查询指令
   // 添加静态变量控制人脸检测
   public static boolean ishaveface = false; // 是否检测到人脸,默认没有人脸
@@ -370,19 +371,17 @@
    * 优化:内存管理和重用对象
    */
   private static class PollingTask implements Runnable {
      private int currentIndex = 0; // 当前索引,用于遍历slotArray
      private int consecutiveFailures = 0; // 连续失败次数
      private static final int MAX_CONSECUTIVE_FAILURES = 5; // 最大连续失败次数
      private final StringBuilder debugBuilder = new StringBuilder(100); // 重用 StringBuilder
       private int currentIndex = 0; // 当前索引,用于遍历slotArray
       private int consecutiveFailures = 0; // 连续失败次数
       private static final int MAX_CONSECUTIVE_FAILURES = 5; // 最大连续失败次数
       private final StringBuilder debugBuilder = new StringBuilder(100); // 重用 StringBuilder
      @Override
      public void run() {
       @Override
       public void run() {
           //System.out.println("轮询查询线程开始运行");
           while (isRunning && !Thread.currentThread().isInterrupted() && !shouldStop.get()) {
               try {
//               System.out.println("查询中.....线程");
                   // 检查是否暂停
                   if (isPaused) {
                       synchronized (lunxun.class) {
@@ -413,81 +412,69 @@
                       continue;
                   }
                   // 新增:根据卡槽状态和查询频率决定是否发送查询
                   boolean sentQuery = false;
                   long currentTime = System.currentTimeMillis();
                   // 遍历卡槽,寻找需要查询的卡槽
                   for (int i = 0; i < slotArray.length && !sentQuery; i++) {
                   // 遍历所有卡槽
                   for (int i = 0; i < slotArray.length; i++) {
                       if (!isRunning || shouldStop.get()) {
                           break;
                       }
                       int slotIndex = (currentIndex + i) % slotArray.length;
                       Fkj slot = slotArray[slotIndex];
                       if (slot != null) {
                           String hasCard = slot.getHasCard();
                           int slotNumber = slotIndex + 1;
                           Long lastQueryTime = lastQueryTimeMap.get(slotNumber);
                           // 新增:如果有人脸检测,则只查询无卡卡槽
                           // 检查是否因为人脸检测需要跳过有卡卡槽
                           if (ishaveface && "1".equals(hasCard)) {
                               // 跳过有卡卡槽的查询
                               // 跳过有卡卡槽,立即继续下一个,不等待
                               if (DEBUG_ENABLED) {
                                   debugBuilder.setLength(0);
                                   debugBuilder.append("检测到人脸,跳过有卡卡槽 ").append(slotNumber).append(" 的查询\n");
                                   SystemDebugDialog.appendAsciiData(debugBuilder.toString());
                               }
                               continue;
                               continue; // 立即继续下一个卡槽,不等待
                           }
                           // 确定查询间隔:只有hasCard="1"的卡槽使用10秒间隔,其他情况(包括"-1")都使用100ms间隔
                           int queryInterval = "1".equals(hasCard) ? HAS_CARD_QUERY_INTERVAL : NO_CARD_QUERY_INTERVAL;
                           // 发送查询指令到当前卡槽
                           boolean sendSuccess = sendQueryToSlot(slotNumber);
                           if (sendSuccess) {
                               // 更新最后查询时间
                               lastQueryTimeMap.put(slotNumber, System.currentTimeMillis());
                               consecutiveFailures = 0;
                           // 检查是否达到查询时间
                           if (lastQueryTime == null || currentTime - lastQueryTime >= queryInterval) {
                               if (sendQueryToSlot(slotNumber)) {
                                   // 更新最后查询时间
                                   lastQueryTimeMap.put(slotNumber, currentTime);
                                   sentQuery = true;
                                   consecutiveFailures = 0;
                                   // 成功发送查询后,等待100ms再继续下一个查询
                                   Thread.sleep(100);
                                   if (DEBUG_ENABLED) {
                                       String status;
                                       if ("1".equals(hasCard)) {
                                           status = "有卡";
                                       } else if ("-1".equals(hasCard)) {
                                           status = "未知";
                                       } else {
                                           status = "无卡";
                                       }
                                       // 使用重用的 StringBuilder 构建调试信息
                                       debugBuilder.setLength(0);
                                       debugBuilder.append("Slot ").append(slotNumber)
                                                  .append(" (").append(status).append(") 查询成功,间隔: ")
                                                  .append(queryInterval).append("ms\n");
                                       SystemDebugDialog.appendAsciiData(debugBuilder.toString());
                               if (DEBUG_ENABLED) {
                                   String status;
                                   if ("1".equals(hasCard)) {
                                       status = "有卡";
                                   } else if ("-1".equals(hasCard)) {
                                       status = "未知";
                                   } else {
                                       status = "无卡";
                                   }
                               } else {
                                   consecutiveFailures++;
                                   if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
                                       logErrorWithRateLimit("consecutive_failures", "lunxun连续失败次数过多,暂停轮询");
                                       pausePolling();
                                       break;
                                   }
                                   debugBuilder.setLength(0);
                                   debugBuilder.append("Slot ").append(slotNumber)
                                              .append(" (").append(status).append(") 查询成功\n");
                                   SystemDebugDialog.appendAsciiData(debugBuilder.toString());
                               }
                           } else {
                               consecutiveFailures++;
                               if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
                                   logErrorWithRateLimit("consecutive_failures", "lunxun连续失败次数过多,暂停轮询");
                                   pausePolling();
                                   break;
                               }
                           }
                           // 发送查询指令后等待50ms,然后继续下一个卡槽
                           Thread.sleep(50);
                       }
                   }
                   // 更新当前索引
                   currentIndex = (currentIndex + 1) % slotArray.length;
                   // 如果没有发送查询,等待一段时间再继续
                   if (!sentQuery) {
                       Thread.sleep(pollingInterval);
                   }
               } catch (InterruptedException e) {
                   //System.out.println("轮询查询线程被中断");
                   Thread.currentThread().interrupt();
@@ -527,45 +514,49 @@
       * 向指定卡槽发送查询指令 - 优化版本
       * 使用缓存指令,优化调试输出
       */
      private boolean sendQueryToSlot(int slotNumber) {
         try {
            // 使用缓存的查询指令
            String queryCommand = getCachedQueryCommand(slotNumber);
//           System.out.println("指令是:"+queryCommand);
            if (DEBUG_ENABLED) {
               SystemDebugDialog.appendAsciiData("send to "+slotNumber+" queryCommand");
            }
      /**
        * 向指定卡槽发送查询指令 - 优化版本
        * 使用缓存指令,优化调试输出
        */
       private boolean sendQueryToSlot(int slotNumber) {
           try {
               // 使用缓存的查询指令
               String queryCommand = getCachedQueryCommand(slotNumber);
               System.out.println(slotNumber+"发送了指令是:"+queryCommand+"时间"+TimestampUtil.getTimestamp());
               if (DEBUG_ENABLED) {
                   SystemDebugDialog.appendAsciiData("send to "+slotNumber+" queryCommand");
               }
            if (queryCommand != null && !queryCommand.trim().isEmpty()) {
               // 发送到串口
               if (queryCommand != null && !queryCommand.trim().isEmpty()) {
                   // 发送到串口
                   if(sendChaxunzhiling) {
                       boolean sendResult = Sendmsg.sendMessage(queryCommand);
                       if (sendResult) {
                           return true;
                       } else {
                           if (DEBUG_ENABLED) {
                               SystemDebugDialog.appendAsciiData(slotNumber+" Send query command to card slot err");
                           }
                           // 发送失败可能是串口断开,更新连接状态
                           serialConnected = false;
                           return false;
                       }
                   } else {
                       return false;
                   }
               } else {
                   logErrorWithRateLimit("empty_query_command", "生成的查询指令为空,卡槽: " + slotNumber);
                   return false;
               }
               if(sendChaxunzhiling) {
                  boolean sendResult = Sendmsg.sendMessage(queryCommand);
                  if (sendResult) {
                     return true;
                  } else {
                     if (DEBUG_ENABLED) {
                        SystemDebugDialog.appendAsciiData(slotNumber+" Send query command to card slot err");
                     }
                     // 发送失败可能是串口断开,更新连接状态
                     serialConnected = false;
                     return false;
                  }
               }else {
                  return false;
               }
            } else {
               logErrorWithRateLimit("empty_query_command", "生成的查询指令为空,卡槽: " + slotNumber);
               return false;
            }
         } catch (Exception e) {
            logErrorWithRateLimit("send_query_exception", "发送查询指令到卡槽 " + slotNumber + " 时发生异常: " + e.getMessage());
            // 发生异常时更新串口连接状态
            serialConnected = false;
            return false;
         }
      }
           } catch (Exception e) {
               logErrorWithRateLimit("send_query_exception", "发送查询指令到卡槽 " + slotNumber + " 时发生异常: " + e.getMessage());
               // 发生异常时更新串口连接状态
               serialConnected = false;
               return false;
           }
       }
   }
   /**