package com.zy.service; import com.rfid.uhf288.RFIDTemplate; import com.rfid.uhf288.RFIDTemplate.TagInfo; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * RFID服务类 * 提供RFID设备检测功能 * Created on 2026/01/10 */ @Slf4j @Service public class RFIDService { private RFIDTemplate rfidTemplate; private String connectionType = ""; // "COM" 或 "NET" /** * 连接RFID设备(网络连接) * * @param ip IP地址 * @param port 端口号 * @return 连接结果 */ public Map connectNetwork(String ip, Integer port) { Map result = new HashMap<>(); try { if (rfidTemplate == null) { rfidTemplate = new RFIDTemplate(); } if (rfidTemplate.isConnected()) { result.put("success", false); result.put("message", "设备已连接,请先断开连接"); return result; } int portNum = port != null ? port : 6000; boolean connected = rfidTemplate.connectNetwork(ip, portNum); if (connected) { connectionType = "NET"; result.put("success", true); result.put("message", "连接成功"); result.put("ip", ip); result.put("port", portNum); log.info("RFID设备网络连接成功 - IP: {}, Port: {}", ip, portNum); } else { result.put("success", false); result.put("message", "连接失败,请检查IP和端口"); } } catch (UnsatisfiedLinkError e) { log.error("RFID设备DLL方法链接失败", e); result.put("success", false); result.put("message", "DLL方法链接失败: " + e.getMessage()); result.put("errorType", "UnsatisfiedLinkError"); result.put("suggestion", "请检查DLL文件是否正确,或尝试重启应用"); } catch (Exception e) { log.error("RFID设备连接异常", e); result.put("success", false); result.put("message", "连接异常: " + e.getMessage()); } return result; } /** * 连接RFID设备(串口连接) * * @param port 串口号 (1=COM1, 2=COM2, 3=COM3...) * @param baud 波特率 (0=9600, 1=19200, 2=38400, 3=57600, 4=115200, 5=230400, 6=460800, 7=921600) * @return 连接结果 */ public Map connectComPort(Integer port, Integer baud) { Map result = new HashMap<>(); try { if (rfidTemplate == null) { rfidTemplate = new RFIDTemplate(); } if (rfidTemplate.isConnected()) { result.put("success", false); result.put("message", "设备已连接,请先断开连接"); return result; } int portNum = port != null ? port : 3; // 默认COM3 boolean connected; if (baud != null && baud >= 0 && baud <= 7) { connected = rfidTemplate.connectComPort(portNum, baud.byteValue()); } else { // 自动检测波特率 connected = rfidTemplate.connectComPortAuto(portNum, -1); } if (connected) { connectionType = "COM"; result.put("success", true); result.put("message", "连接成功"); result.put("port", "COM" + portNum); log.info("RFID设备串口连接成功 - COM{}", portNum); } else { result.put("success", false); result.put("message", "连接失败,请检查串口和波特率"); } } catch (UnsatisfiedLinkError e) { log.error("RFID设备DLL方法链接失败", e); result.put("success", false); result.put("message", "DLL方法链接失败: " + e.getMessage()); result.put("errorType", "UnsatisfiedLinkError"); result.put("suggestion", "请检查DLL文件是否正确,或尝试重启应用"); } catch (Exception e) { log.error("RFID设备连接异常", e); result.put("success", false); result.put("message", "连接异常: " + e.getMessage()); } return result; } /** * 检测RFID标签(单次检测) * 只在检测到标签时打印日志 * * @param scanTime 扫描时间(单位: 100ms,默认5) * @return 检测结果 */ public Map detectTags(Integer scanTime) { Map result = new HashMap<>(); List> tagList = new ArrayList<>(); try { if (rfidTemplate == null || !rfidTemplate.isConnected()) { result.put("success", false); result.put("message", "设备未连接,请先连接设备"); return result; } int scanTimeValue = scanTime != null ? scanTime : 5; // 默认5*100ms=500ms List tags = rfidTemplate.readTags(4, 0, scanTimeValue); if (tags != null && !tags.isEmpty()) { // 检测到标签时才打印日志 for (TagInfo tag : tags) { Map tagMap = new HashMap<>(); tagMap.put("epc", tag.epc); tagMap.put("rssi", tag.rssi); tagMap.put("antenna", tag.antenna); tagMap.put("timestamp", tag.timestamp); tagList.add(tagMap); // 打印检测到的标签信息 log.info(">>> 检测到RFID标签 - EPC: {}, RSSI: {}dBm, 天线: {}", tag.epc, tag.rssi, tag.antenna); } result.put("success", true); result.put("message", "检测到 " + tags.size() + " 个标签"); result.put("count", tags.size()); result.put("tags", tagList); } else { // 检测不到标签时不打印日志(只返回结果) result.put("success", true); result.put("message", "未检测到标签"); result.put("count", 0); result.put("tags", tagList); } } catch (Exception e) { log.error("RFID标签检测异常", e); result.put("success", false); result.put("message", "检测异常: " + e.getMessage()); } return result; } /** * 断开RFID设备连接 * * @return 断开结果 */ public Map disconnect() { Map result = new HashMap<>(); try { if (rfidTemplate != null && rfidTemplate.isConnected()) { rfidTemplate.disconnect(); connectionType = ""; result.put("success", true); result.put("message", "断开连接成功"); log.info("RFID设备连接已断开"); } else { result.put("success", false); result.put("message", "设备未连接"); } } catch (Exception e) { log.error("RFID设备断开连接异常", e); result.put("success", false); result.put("message", "断开连接异常: " + e.getMessage()); } return result; } /** * 获取连接状态 * * @return 连接状态 */ public Map getConnectionStatus() { Map result = new HashMap<>(); try { boolean connected = rfidTemplate != null && rfidTemplate.isConnected(); result.put("connected", connected); result.put("connectionType", connected ? connectionType : ""); result.put("message", connected ? "设备已连接" : "设备未连接"); } catch (Exception e) { log.error("获取RFID连接状态异常", e); result.put("connected", false); result.put("message", "获取状态异常: " + e.getMessage()); } return result; } /** * 诊断DLL加载状态 * * @return 诊断信息 */ public Map diagnoseDll() { Map result = new HashMap<>(); try { // 检查DLL文件是否存在(使用项目根目录的相对路径) String projectBaseDir = System.getProperty("user.dir"); java.io.File dllFile1 = new java.io.File(projectBaseDir, "src/main/resources/lib/com_rfid_uhf288_Device.dll"); java.io.File dllFile2 = new java.io.File(projectBaseDir, "src/main/resources/lib/UHFReader288.dll"); // 也检查临时目录中的DLL文件 String tempDir = System.getProperty("java.io.tmpdir"); java.io.File tempDll1 = new java.io.File(tempDir + "rfid-lib/com_rfid_uhf288_Device.dll"); java.io.File tempDll2 = new java.io.File(tempDir + "rfid-lib/UHFReader288.dll"); Map dllInfo = new HashMap<>(); Map sourceDll1 = new HashMap<>(); sourceDll1.put("exists", dllFile1.exists()); sourceDll1.put("size", dllFile1.exists() ? dllFile1.length() : 0); sourceDll1.put("path", dllFile1.getAbsolutePath()); sourceDll1.put("tempExists", tempDll1.exists()); sourceDll1.put("tempSize", tempDll1.exists() ? tempDll1.length() : 0); sourceDll1.put("tempPath", tempDll1.getAbsolutePath()); if (dllFile1.exists() && tempDll1.exists()) { sourceDll1.put("sizeMatch", dllFile1.length() == tempDll1.length()); } dllInfo.put("com_rfid_uhf288_Device.dll", sourceDll1); Map sourceDll2 = new HashMap<>(); sourceDll2.put("exists", dllFile2.exists()); sourceDll2.put("size", dllFile2.exists() ? dllFile2.length() : 0); sourceDll2.put("path", dllFile2.getAbsolutePath()); sourceDll2.put("tempExists", tempDll2.exists()); sourceDll2.put("tempSize", tempDll2.exists() ? tempDll2.length() : 0); sourceDll2.put("tempPath", tempDll2.getAbsolutePath()); if (dllFile2.exists() && tempDll2.exists()) { sourceDll2.put("sizeMatch", dllFile2.length() == tempDll2.length()); } dllInfo.put("UHFReader288.dll", sourceDll2); result.put("dllFiles", dllInfo); // 检查Device类是否可以实例化 boolean deviceCreated = false; String deviceError = null; try { if (rfidTemplate == null) { rfidTemplate = new RFIDTemplate(); } deviceCreated = true; } catch (Exception e) { deviceError = e.getMessage(); } result.put("deviceCreated", deviceCreated); if (deviceError != null) { result.put("deviceError", deviceError); } // 检查native方法是否可用(实际尝试调用验证) boolean nativeMethodAvailable = false; String nativeMethodError = null; if (deviceCreated && rfidTemplate != null) { try { // 实际尝试调用native方法来验证(使用无效参数,只测试方法链接) // 如果方法不存在或链接失败,会抛出UnsatisfiedLinkError boolean wasConnected = rfidTemplate.isConnected(); if (!wasConnected) { // 尝试连接一个无效的IP地址,只测试native方法是否可用 // 注意:这里会失败,但我们只关心方法是否链接成功 try { // 调用connectNetwork,如果native方法链接失败会抛出UnsatisfiedLinkError boolean connected = rfidTemplate.connectNetwork("127.0.0.1", 9999); // 如果执行到这里,说明native方法链接成功(即使连接失败) nativeMethodAvailable = true; // 如果意外连接成功,断开连接 if (connected) { rfidTemplate.disconnect(); } } catch (UnsatisfiedLinkError e) { // 如果抛出UnsatisfiedLinkError,说明native方法链接失败 nativeMethodError = "DLL native方法链接失败: " + e.getMessage(); nativeMethodAvailable = false; } catch (Exception e) { // 其他异常(如连接失败、网络错误等)是正常的,说明方法链接成功 // 检查异常类型,UnsatisfiedLinkError应该已经被上面的catch捕获 if (e.getCause() instanceof UnsatisfiedLinkError) { nativeMethodError = "DLL native方法链接失败: " + e.getCause().getMessage(); nativeMethodAvailable = false; } else { // 其他异常说明方法链接成功,只是调用失败 nativeMethodAvailable = true; } } } else { // 如果已经连接,说明之前调用过native方法,方法应该是可用的 nativeMethodAvailable = true; } } catch (UnsatisfiedLinkError e) { nativeMethodError = "DLL native方法链接失败: " + e.getMessage(); nativeMethodAvailable = false; } catch (Exception e) { // 其他异常不影响判断 if (nativeMethodError == null) { nativeMethodError = "验证异常: " + e.getMessage(); } } } result.put("nativeMethodAvailable", nativeMethodAvailable); if (nativeMethodError != null) { result.put("nativeMethodError", nativeMethodError); } // 提供建议 List suggestions = new ArrayList<>(); if (!dllFile1.exists()) { suggestions.add("DLL文件不存在: com_rfid_uhf288_Device.dll"); suggestions.add("请检查 src/main/resources/lib/ 目录"); } else { suggestions.add("DLL文件存在: com_rfid_uhf288_Device.dll (大小: " + dllFile1.length() + " 字节)"); // 检查DLL文件是否可能是文本文件(被Maven过滤损坏) if (dllFile1.length() < 1000) { suggestions.add("警告:DLL文件大小异常小,可能被损坏"); } } if (!deviceCreated) { suggestions.add("Device类实例化失败,请检查DLL文件是否存在"); } else if (!nativeMethodAvailable) { suggestions.add("DLL已加载,但native方法不可用"); suggestions.add("错误信息: " + (nativeMethodError != null ? nativeMethodError : "未知错误")); suggestions.add("可能原因:1. DLL版本不匹配 2. 方法签名不匹配 3. DLL文件损坏"); suggestions.add("解决方案:"); suggestions.add("1. 从demo项目(testdemo-jni)中复制DLL文件到当前项目"); suggestions.add("2. 确保DLL文件没有被Maven资源过滤处理"); suggestions.add("3. 检查DLL文件大小是否与demo项目中的一致"); suggestions.add("4. 尝试重新编译项目: mvn clean compile"); suggestions.add("5. 检查临时目录中的DLL文件: " + System.getProperty("java.io.tmpdir") + "rfid-lib"); } else { suggestions.add("DLL加载正常,native方法可用"); } result.put("suggestions", suggestions); result.put("message", nativeMethodAvailable ? "DLL状态正常" : "DLL状态异常"); } catch (Exception e) { log.error("RFID DLL诊断异常", e); result.put("error", "诊断异常: " + e.getMessage()); } return result; } }