package chushihua;
|
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import dialog.Dingshidialog;
|
import home.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<Integer, String> statusTextCache = new ConcurrentHashMap<>();
|
private static final Map<Integer, String> 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<Fkj> getAllSlots() {
|
List<Fkj> 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));
|
}
|
|
/**
|
* 根据状态码和故障码判断是否有卡 - 优化版本
|
*/
|
@SuppressWarnings("unused")
|
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(() -> {
|
Dingshidialog.showTimedDialog(
|
null, // 父窗口,可以为null
|
5, // 显示3秒
|
slotNumber+"号卡槽还卡成功感谢您的使用"
|
);
|
});
|
//System.out.println("卡槽 " + slotNumber + " 还卡成功,卡号从 " + oldCardNumber + " 变为 " + newCardNumber);
|
}
|
}
|
|
/**
|
* 静态方法:根据卡槽编号改变是否有卡的属性值为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;
|
}
|
}
|