package chushihua; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import xitongshezhi.Fkj; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; /** * 卡槽管理类 - 优化版本 * 用于初始化和管理60个卡槽,优化内存使用和性能 */ public class SlotManager { public static Fkj[] slotArray; // 使用数组替代List,提高访问性能 public static Fkj[] getSlotArray() { return slotArray; } public static void setSlotArray(Fkj[] slotArray) { SlotManager.slotArray = slotArray; } private static final int TOTAL_SLOTS = 60; private static final String UNKNOWN_VALUE = "-1"; // 时间格式化器 - 静态常量 private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 状态缓存 - 减少字符串创建 private static final Map statusTextCache = new ConcurrentHashMap<>(); private static final Map faultTextCache = new ConcurrentHashMap<>(); // 常用字符串常量 - 避免重复创建 private static final String SLOT_NUMBER = "卡槽编号"; private static final String CARD_NUMBER = "卡编号"; private static final String HAS_CARD = "是否有卡"; private static final String WORK_STATUS = "工作状态"; private static final String VOLTAGE = "电压"; private static final String CURRENT = "电流"; private static final String FAULT = "故障"; private static final String UPDATE_TIME = "更新时间"; private static final String SLOT_NUMBER_EN = "slotnumber"; private static final String CARD_NUMBER_EN = "cardnumber"; private static final String HAS_CARD_EN = "hascard"; private static final String WORK_STATUS_EN = "workstatus"; private static final String VOLTAGE_EN = "voltage"; private static final String CURRENT_EN = "current"; private static final String FAULT_EN = "fault"; private static final String UPDATE_TIME_EN = "updatetime"; /** * 构造函数 - 初始化所有卡槽 */ public SlotManager() { initializeSlots(); } /** * 初始化所有卡槽 - 使用数组优化 */ private void initializeSlots() { slotArray = new Fkj[TOTAL_SLOTS]; for (int i = 0; i < TOTAL_SLOTS; i++) { Fkj slot = new Fkj(); // 设置卡槽编号 (从1开始) slot.setSlotNumber(String.valueOf(i + 1)); // 初始化其他属性为未知值"-1" slot.setCardNumber(UNKNOWN_VALUE); slot.setHasCard(UNKNOWN_VALUE); slot.setWorkStatus(UNKNOWN_VALUE); slot.setVoltage(UNKNOWN_VALUE); slot.setCurrent(UNKNOWN_VALUE); slot.setFault(UNKNOWN_VALUE); slot.setUpdateTime(UNKNOWN_VALUE); slotArray[i] = slot; } // 预初始化缓存 initializeCaches(); } /** * 预初始化状态和故障文本缓存 */ private void initializeCaches() { // 预缓存常见状态值 for (int i = 0; i <= 6; i++) { getCachedStatusText(i); } // 预缓存常见故障值 for (int i = 0; i <= 5; i++) { getCachedFaultText(i); } } /** * 修改指定卡槽的属性值 - 优化版本 */ public boolean updateSlotAttribute(int slotNumber, String attributeName, String value) { // 验证卡槽编号范围 (使用快速边界检查) if (!isValidSlotNumber(slotNumber)) { System.err.println("错误:卡槽编号必须在1-" + TOTAL_SLOTS + "之间"); return false; } // 验证属性名称 if (attributeName == null || attributeName.trim().isEmpty()) { System.err.println("错误:属性名称不能为空"); return false; } // 获取对应的卡槽对象 (数组直接访问,O(1)时间复杂度) Fkj slot = slotArray[slotNumber - 1]; String attrLower = attributeName.toLowerCase(); // 根据属性名称设置对应的值 switch (attrLower) { case SLOT_NUMBER: case SLOT_NUMBER_EN: slot.setSlotNumber(value); break; case CARD_NUMBER: case CARD_NUMBER_EN: slot.setCardNumber(value); break; case HAS_CARD: case HAS_CARD_EN: if (isValidHasCardValue(value)) { slot.setHasCard(value); // 自动更新时间 slot.setUpdateTime(getCurrentTime()); } else { System.err.println("错误:无效的有卡状态值 '" + value + "'"); return false; } break; case WORK_STATUS: case WORK_STATUS_EN: slot.setWorkStatus(value); break; case VOLTAGE: case VOLTAGE_EN: slot.setVoltage(value); break; case CURRENT: case CURRENT_EN: slot.setCurrent(value); break; case FAULT: case FAULT_EN: slot.setFault(value); break; case UPDATE_TIME: case UPDATE_TIME_EN: slot.setUpdateTime(value); break; default: System.err.println("错误:未知的属性名称 '" + attributeName + "'"); return false; } return true; } /** * 获取指定卡槽的信息 - 优化版本 */ public Fkj getSlotInfo(int slotNumber) { if (!isValidSlotNumber(slotNumber)) { System.err.println("错误:卡槽编号必须在1-" + TOTAL_SLOTS + "之间"); return null; } return slotArray[slotNumber - 1]; } /** * 获取所有卡槽的列表 */ public List getAllSlots() { List copy = new ArrayList<>(TOTAL_SLOTS); for (Fkj slot : slotArray) { copy.add(slot); } return copy; } /** * 获取卡槽总数 */ public int getTotalSlots() { return TOTAL_SLOTS; } /** * 打印所有卡槽的概要信息 - 优化版本 */ public void printAllSlotsSummary() { System.out.println("=== 卡槽概要信息 ==="); System.out.println("总卡槽数: " + TOTAL_SLOTS); for (Fkj slot : slotArray) { System.out.printf("卡槽 %s: 卡编号=%s, 有卡=%s, 状态=%s, 故障=%s%n", slot.getSlotNumber(), slot.getCardNumber(), slot.getHasCard(), slot.getWorkStatus(), slot.getFault()); } } /** * 打印指定卡槽的详细信息 */ public void printSlotDetail(int slotNumber) { Fkj slot = getSlotInfo(slotNumber); if (slot != null) { System.out.println("=== 卡槽 " + slotNumber + " 详细信息 ==="); System.out.println(slot.toString()); } } /** * 设置指定卡槽的"是否有卡"状态 - 优化版本 */ public boolean setSlotHasCard(int slotNumber, String hasCardValue) { if (!isValidSlotNumber(slotNumber) || !isValidHasCardValue(hasCardValue)) { return false; } Fkj slot = slotArray[slotNumber - 1]; slot.setHasCard(hasCardValue); slot.setUpdateTime(getCurrentTime()); return true; } /** * 根据卡槽编号获取卡槽是否有卡状态(静态方法)- 优化版本 */ public static String getSlotHasCardStatus(int slotNumber) { if (!isValidSlotNumber(slotNumber)) { return null; } return slotArray[slotNumber - 1].getHasCard(); } /** * 获取有卡数量与卡槽总数的比例字符串(静态方法)- 优化版本 */ public static String getHasCardRatio() { int hasCardCount = 0; for (Fkj slot : slotArray) { if ("1".equals(slot.getHasCard())) { hasCardCount++; } } return hasCardCount + "/" + TOTAL_SLOTS; } /** * 新增:根据串口协议解析器的状态更新来更新卡槽详细信息 - 优化版本 */ public static boolean gengxinshuxingzhi( int slotNumber, String cardNumber, String hascard, String workStatus, String voltage, String current, String falt) { if (!isValidSlotNumber(slotNumber)) { return false; } Fkj slot = slotArray[slotNumber-1]; // 获取更新前的卡号用于比较 String oldCardNumber = slot.getCardNumber(); // 更新卡槽属性 slot.setCardNumber(cardNumber); slot.setHasCard(hascard); slot.setWorkStatus(workStatus); slot.setVoltage(voltage); slot.setCurrent(current); slot.setFault(falt); // 更新时间 slot.setUpdateTime(getCurrentTime()); // 检测卡号变化并弹出提示 checkCardInsertionAndShowDialog(slotNumber, oldCardNumber, cardNumber); return true; } /** * 获取缓存的状态文本 */ private static String getCachedStatusText(int status) { return statusTextCache.computeIfAbsent(status, k -> String.valueOf(k)); } /** * 获取缓存的故障文本 */ private static String getCachedFaultText(int fault) { return faultTextCache.computeIfAbsent(fault, k -> String.valueOf(k)); } /** * 根据状态码和故障码判断是否有卡 - 优化版本 */ private String determineHasCardFromStatus(int status, int fault) { // 优化:使用数值比较替代字符串操作 if (fault != 0) { return "1"; // 假设有故障时仍然可能有卡 } switch (status) { case 0: return "0"; // 无效/无卡 case 1: // 待机(有卡但未充电) case 2: // 充电中 case 3: // 已充满 case 4: // 故障 case 5: // 授权到期 case 6: // 通信超时 return "1"; default: return UNKNOWN_VALUE; } } /** * 获取工作状态统计 - 优化版本 */ public int[] getWorkStatusStatistics() { int[] stats = new int[7]; for (Fkj slot : slotArray) { String status = slot.getWorkStatus(); if (!UNKNOWN_VALUE.equals(status)) { try { int statusCode = Integer.parseInt(status); if (statusCode >= 0 && statusCode < stats.length) { stats[statusCode]++; } } catch (NumberFormatException e) { // 忽略格式错误 } } } return stats; } /** * 获取故障统计 - 优化版本 */ public int[] getFaultStatistics() { int[] stats = new int[6]; for (Fkj slot : slotArray) { String fault = slot.getFault(); if (!UNKNOWN_VALUE.equals(fault)) { try { int faultCode = Integer.parseInt(fault); if (faultCode >= 0 && faultCode < stats.length) { stats[faultCode]++; } } catch (NumberFormatException e) { // 忽略格式错误 } } } return stats; } /** * 获取卡槽的详细状态信息 - 优化版本 */ public String getSlotDetailedStatus(int slotNumber) { if (!isValidSlotNumber(slotNumber)) { return "无效卡槽编号"; } Fkj slot = slotArray[slotNumber - 1]; return String.format("卡槽 %d: 有卡=%s, 状态=%s, 电压=%s, 电流=%s, 故障=%s, 更新时间=%s", slotNumber, slot.getHasCard(), slot.getWorkStatus(), slot.getVoltage(), slot.getCurrent(), slot.getFault(), slot.getUpdateTime()); } /** * 重置所有卡槽状态为未知 - 优化版本 */ public void resetAllSlots() { for (Fkj slot : slotArray) { slot.setCardNumber(UNKNOWN_VALUE); slot.setHasCard(UNKNOWN_VALUE); slot.setWorkStatus(UNKNOWN_VALUE); slot.setVoltage(UNKNOWN_VALUE); slot.setCurrent(UNKNOWN_VALUE); slot.setFault(UNKNOWN_VALUE); slot.setUpdateTime(UNKNOWN_VALUE); } System.out.println("所有卡槽状态已重置为未知"); } /** * 验证卡槽编号是否有效 */ private static boolean isValidSlotNumber(int slotNumber) { return slotNumber >= 1 && slotNumber <= TOTAL_SLOTS; } /** * 验证有卡状态值是否有效 */ private static boolean isValidHasCardValue(String hasCardValue) { return "1".equals(hasCardValue) || "0".equals(hasCardValue) || UNKNOWN_VALUE.equals(hasCardValue); } /** * 获取当前时间字符串 */ private static String getCurrentTime() { return LocalDateTime.now().format(TIME_FORMATTER); } /** * 清理缓存(在状态定义变化时调用) */ public static void clearCaches() { statusTextCache.clear(); faultTextCache.clear(); } /** * 获取缓存统计信息(用于监控) */ public static void printCacheStats() { System.out.println("状态缓存大小: " + statusTextCache.size()); System.out.println("故障缓存大小: " + faultTextCache.size()); } /** * 统计充电中的卡槽数量 * @return 充电中的卡槽数量字符串 */ public static String getChargingCount() { int count = 0; for (Fkj slot : slotArray) { if ("2".equals(slot.getWorkStatus())) { count++; } } return String.valueOf(count); } /** * 统计已充满的卡槽数量 * @return 已充满的卡槽数量字符串 */ public static String getFullyChargedCount() { int count = 0; for (Fkj slot : slotArray) { if ("3".equals(slot.getWorkStatus())) { count++; } } return String.valueOf(count); } /** * 统计故障的卡槽数量 * @return 故障的卡槽数量字符串 */ public static String getFaultCount() { int count = 0; for (Fkj slot : slotArray) { if ("4".equals(slot.getWorkStatus())) { count++; } } return String.valueOf(count); } /** * 统计通信超时的卡槽数量 * @return 通信超时的卡槽数量字符串 */ public static String getCommTimeoutCount() { int count = 0; for (Fkj slot : slotArray) { if ("6".equals(slot.getWorkStatus())) { count++; } } return String.valueOf(count); } /** * 新增:检测卡号变化并弹出还卡成功提示 */ private static void checkCardInsertionAndShowDialog(int slotNumber, String oldCardNumber, String newCardNumber) { // 检查卡号是否从"0000"变为非"0000" if ("0000".equals(oldCardNumber) && !"0000".equals(newCardNumber)) { // 在事件分发线程中显示对话框 javax.swing.SwingUtilities.invokeLater(() -> { xitongshezhi.Dingshidialog.showTimedDialog( null, // 父窗口,可以为null 5, // 显示3秒 "还卡成功,感谢您的使用", "" // 音频文件,可以为空 ); }); System.out.println("卡槽 " + slotNumber + " 还卡成功,卡号从 " + oldCardNumber + " 变为 " + newCardNumber); } } }