张世豪
2025-11-28 7acfc864d11de1fc41cabc2a5d4fad3894c2e5b0
src/chushihua/SlotManager.java
@@ -5,7 +5,9 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import xitongshezhi.Fkj;
import dialog.Dingshidialog;
import home.Fkj;
import publicway.TimestampUtil;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@@ -53,6 +55,9 @@
   private static final String CURRENT_EN = "current";
   private static final String FAULT_EN = "fault";
   private static final String UPDATE_TIME_EN = "updatetime";
   // 在属性定义区域添加常量
   private static final String RECEIVE_CARD_COMMAND_TIME = "收到发卡指令时间";
   private static final String RECEIVE_CARD_COMMAND_TIME_EN = "receivecardcommandtime";
   /**
    * 构造函数 - 初始化所有卡槽
@@ -79,7 +84,7 @@
         slot.setCurrent(UNKNOWN_VALUE);
         slot.setFault(UNKNOWN_VALUE);
         slot.setUpdateTime(UNKNOWN_VALUE);
         slot.setReceiveCardCommandTime(UNKNOWN_VALUE); // 新增:初始化收到发卡指令时间为-1
         slotArray[i] = slot;
      }
@@ -163,6 +168,11 @@
      case UPDATE_TIME_EN:
         slot.setUpdateTime(value);
         break;
         // 在 updateSlotAttribute 方法的 switch 语句中添加新属性的处理
      case RECEIVE_CARD_COMMAND_TIME:
      case RECEIVE_CARD_COMMAND_TIME_EN:
          slot.setReceiveCardCommandTime(value);
          break;
      default:
         System.err.println("错误:未知的属性名称 '" + attributeName + "'");
         return false;
@@ -204,8 +214,8 @@
    * 打印所有卡槽的概要信息 - 优化版本
    */
   public void printAllSlotsSummary() {
      System.out.println("=== 卡槽概要信息 ===");
      System.out.println("总卡槽数: " + TOTAL_SLOTS);
      //System.out.println("=== 卡槽概要信息 ===");
      //System.out.println("总卡槽数: " + TOTAL_SLOTS);
      for (Fkj slot : slotArray) {
         System.out.printf("卡槽 %s: 卡编号=%s, 有卡=%s, 状态=%s, 故障=%s%n",
@@ -223,8 +233,8 @@
   public void printSlotDetail(int slotNumber) {
      Fkj slot = getSlotInfo(slotNumber);
      if (slot != null) {
         System.out.println("=== 卡槽 " + slotNumber + " 详细信息 ===");
         System.out.println(slot.toString());
         //System.out.println("=== 卡槽 " + slotNumber + " 详细信息 ===");
         //System.out.println(slot.toString());
      }
   }
@@ -318,6 +328,7 @@
   /**
    * 根据状态码和故障码判断是否有卡 - 优化版本
    */
   @SuppressWarnings("unused")
   private String determineHasCardFromStatus(int status, int fault) {
      // 优化:使用数值比较替代字符串操作
      if (fault != 0) {
@@ -414,8 +425,9 @@
         slot.setCurrent(UNKNOWN_VALUE);
         slot.setFault(UNKNOWN_VALUE);
         slot.setUpdateTime(UNKNOWN_VALUE);
         slot.setReceiveCardCommandTime(UNKNOWN_VALUE); // 新增:重置收到发卡指令时间
      }
      System.out.println("所有卡槽状态已重置为未知");
      //System.out.println("所有卡槽状态已重置为未知");
   }
@@ -453,8 +465,8 @@
    * 获取缓存统计信息(用于监控)
    */
   public static void printCacheStats() {
      System.out.println("状态缓存大小: " + statusTextCache.size());
      System.out.println("故障缓存大小: " + faultTextCache.size());
      //System.out.println("状态缓存大小: " + statusTextCache.size());
      //System.out.println("故障缓存大小: " + faultTextCache.size());
   }
   /**
@@ -521,14 +533,84 @@
      if ("0000".equals(oldCardNumber) && !"0000".equals(newCardNumber)) {
         // 在事件分发线程中显示对话框
         javax.swing.SwingUtilities.invokeLater(() -> {
            xitongshezhi.Dingshidialog.showTimedDialog(
            Dingshidialog.showTimedDialog(
                  null, // 父窗口,可以为null
                  5,    // 显示3秒
                  "还卡成功,感谢您的使用",
                  ""    // 音频文件,可以为空
                  slotNumber+"号卡槽还卡成功感谢您的使用"
                  );
         });
         System.out.println("卡槽 " + slotNumber + " 还卡成功,卡号从 " + oldCardNumber + " 变为 " + newCardNumber);
//       System.out.println("还卡成功" + slotNumber + " 还卡成功,卡号从 " + oldCardNumber + " 变为 " + newCardNumber);
         System.out.println("还卡成功"+slotNumber +"时间"+ " 还卡成功,卡号从 " + oldCardNumber + " 变为 " + newCardNumber+TimestampUtil.getTimestamp());
      }
   }
   /**
    * 静态方法:根据卡槽编号改变是否有卡的属性值为0(无卡)
    * @param slotNumber 卡槽编号(从1开始)
    * @param caozuo 操作类型:1表示管理员,0表示系统
    * @return 修改成功返回true,否则返回false
    */
   public static boolean changgehaska(int slotNumber, int caozuo) {
       if (!isValidSlotNumber(slotNumber)) {
           return false;
       }
       Fkj slot = slotArray[slotNumber - 1];
       slot.setHasCard("0");
       slot.setCardNumber("0000");
       slot.setUpdateTime(getCurrentTime());
       // 记录取卡日志
       String operator =caozuo==1? "管理员" : "系统";
       String logMessage = String.format("取卡操作:卡槽%d被%s取卡", slotNumber, operator);
       dialog.Charulog.logOperation(logMessage);
       return true;
   }
   /**
    * 轮询检查卡槽状态,对未取出的卡槽重新发送开门指令
    * @param type 操作类型:1-服务器发卡,2-管理员发卡
    */
   public static void pollAndResendOpenCommand(int type) {
       // 使用自定义的时间格式器
       DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
       for (int i = 0; i < TOTAL_SLOTS; i++) {
           Fkj slot = slotArray[i];
           int slotId = i + 1;
           // 获取收到发卡指令时间和卡号
           String receiveTime = slot.getReceiveCardCommandTime();
           String cardNumber = slot.getCardNumber();
           // 检查条件:收到指令时间不为-1,卡号不等于0000
           if (!UNKNOWN_VALUE.equals(receiveTime) && !"0000".equals(cardNumber)) {
               try {
                   // 解析时间并计算时间差
                   LocalDateTime currentTime = LocalDateTime.now();
                   LocalDateTime receiveDateTime = LocalDateTime.parse(receiveTime, formatter);
                   long timeDiff = java.time.Duration.between(receiveDateTime, currentTime).toMillis();
                   // 如果时间差小于10秒,重新发送开门指令
                   if (timeDiff < 10000) {
                       // 调用发送开门指令方法
                       boolean sendResult = chuankou.Sendmsg.opendoorzhiling(slotId, type);
                       if (sendResult) {
                           System.out.println("重新发送开门指令 - 卡槽" + slotId + ",卡号: " + cardNumber +
                                            ",时间差: " + timeDiff + "ms");
                       }
                       // 间隔50毫秒
                       Thread.sleep(50);
                   }
               } catch (Exception e) {
                   System.err.println("处理卡槽" + slotId + "时发生错误: " + e.getMessage());
                   // 继续处理下一个卡槽
               }
           }
       }
   }
}