diff --git a/RFID.md b/RFID.md index 5259e62..0bb850d 100644 --- a/RFID.md +++ b/RFID.md @@ -58,8 +58,15 @@ # 业务逻辑 -## 设备记录成功率逻辑 -- +## 设备记录 +### 分页查询 +- 分页查询逻辑参考rfid-middleware\ruoyi-modules\hw-rfid\ShardingQuery.md文档 +### 条码信息显示空格符号的空格处理 +- 202020202020205357303034 设备返回的这个 20 转成 ascii 是个空格 +- 条码信息原始值可能包含空格(0x20) 和 NULL 字符(0x00) 等不可见字符,例如设备返回 `202020202020205357303034`,其中 `20` 转成 ASCII 是空格。 +- Mapper 层在 `RfidReadRecordMapper.xml` 中对 `barcode` 使用 `TRIM(t.barcode) as barcode` 去掉前后空格,但对 NULL/控制字符无效(SQL 的 `TRIM()` 只能去除标准空格 ASCII 32)。 +- Service 层在 `RfidReadRecordServiceImpl` 中通过 `cleanBarcodeList / cleanBarcode`,使用正则 `Pattern.compile("[\\s\\x00-\\x1F\\x7F]+")` 清理所有不可见字符,只保留业务字符,最终前端看到的条码为无空格的纯业务值(例如 `QNC006`)。 +### 设备记录成功率逻辑 - 成功率统计接口:`GET /rfid/dashboard/successRate`,按小时(0–23 点)返回折线图数据,用于前端折线图展示. - 统计维度:后端自动以当前系统日期作为“今日”,**同时统计昨日同一小时的成功率**,前端无需传任何查询参数. - 分表与时间范围:分别通过 `RfidReadRecordTableHelper.getTableName(今日)` 与 `RfidReadRecordTableHelper.getTableName(昨日)` 生成当日与昨日分表(如 `rfid_read_record_20251126`),各自只统计 `00:00:00` 至 `23:59:59` 之间的读取记录. diff --git a/ruoyi-modules/hw-rfid/src/main/java/org/dromara/rfid/service/impl/RfidReadRecordServiceImpl.java b/ruoyi-modules/hw-rfid/src/main/java/org/dromara/rfid/service/impl/RfidReadRecordServiceImpl.java index 99e6317..8d6f46e 100644 --- a/ruoyi-modules/hw-rfid/src/main/java/org/dromara/rfid/service/impl/RfidReadRecordServiceImpl.java +++ b/ruoyi-modules/hw-rfid/src/main/java/org/dromara/rfid/service/impl/RfidReadRecordServiceImpl.java @@ -24,6 +24,7 @@ import org.dromara.rfid.service.IRfidReadRecordService; import java.util.Date; import java.util.List; import java.util.Collection; +import java.util.regex.Pattern; /** * 读取记录Service业务层处理 @@ -41,6 +42,12 @@ public class RfidReadRecordServiceImpl implements IRfidReadRecordService { private final RfidReadRecordMapper baseMapper; + /** + * 用于清理条码中的不可见字符(空格、NULL字符、控制字符等) + * 匹配:空格、NULL字符(\x00)、制表符、换行符等控制字符 + */ + private static final Pattern BARCODE_CLEAN_PATTERN = Pattern.compile("[\\s\\x00-\\x1F\\x7F]+"); + /** * 查询读取记录 * @@ -51,7 +58,10 @@ public class RfidReadRecordServiceImpl implements IRfidReadRecordService { @Override public RfidReadRecordVo queryById(Long id, Date queryDate) { String tableName = RfidReadRecordTableHelper.getTableName(queryDate); - return baseMapper.selectCustomRfidReadRecordVoById(tableName, id); + RfidReadRecordVo record = baseMapper.selectCustomRfidReadRecordVoById(tableName, id); + // 清理条码中的不可见字符 + cleanBarcode(record); + return record; } /** @@ -81,6 +91,9 @@ public class RfidReadRecordServiceImpl implements IRfidReadRecordService { ? baseMapper.selectCustomRfidReadRecordVoPage(tableNames.get(0), pageQuery.build(), lqw) : baseMapper.selectCustomRfidReadRecordVoPageMultiTable(tableNames, pageQuery.build(), lqw); + // 清理条码中的不可见字符 + cleanBarcodeList(result.getRecords()); + return TableDataInfo.build(result); } @@ -112,15 +125,22 @@ public class RfidReadRecordServiceImpl implements IRfidReadRecordService { // 采样查询:每 N 分钟取一条代表数据 // tableNames.size() == 1 表示只涉及一张分表,直接调用单表采样SQL; // 否则说明跨多天/多张分表,调用多表采样SQL进行 UNION ALL 聚合。 - return tableNames.size() == 1 + List sampledRecords = tableNames.size() == 1 ? baseMapper.selectWithSampling(tableNames.get(0), samplingInterval, lqw) : baseMapper.selectWithSamplingMultiTable(tableNames, samplingInterval, lqw); + // 清理条码中的不可见字符 + cleanBarcodeList(sampledRecords); + return sampledRecords; } // 普通查询 - return tableNames.size() == 1 + List records = tableNames.size() == 1 ? baseMapper.selectCustomRfidReadRecordVoList(tableNames.get(0), lqw) : baseMapper.selectCustomRfidReadRecordVoListMultiTable(tableNames, lqw); + + // 清理条码中的不可见字符 + cleanBarcodeList(records); + return records; } /** @@ -151,6 +171,53 @@ public class RfidReadRecordServiceImpl implements IRfidReadRecordService { return lqw; } + /** + * 批量清理条码中的不可见字符 + * + * @param records 记录列表 + */ + private void cleanBarcodeList(List records) { + if (CollUtil.isEmpty(records)) { + return; + } + for (RfidReadRecordVo record : records) { + cleanBarcode(record); + } + } + + /** + * 清理单条记录的条码不可见字符 + *

+ * 设备返回的条码可能包含空格(0x20)、NULL字符(0x00)等不可见字符, + * 需要在返回前端前清理掉。 + *

+ * + * @param record 记录 + */ + private void cleanBarcode(RfidReadRecordVo record) { + if (record == null || record.getBarcode() == null) { + return; + } + String originalBarcode = record.getBarcode(); + // 使用正则替换所有不可见字符,仅保留可见业务字符 + String cleanedBarcode = BARCODE_CLEAN_PATTERN.matcher(originalBarcode).replaceAll(""); + record.setBarcode(cleanedBarcode); + } + + /** + * 将字符串转换为十六进制表示,用于调试 + */ + private String toHexString(String str) { + if (str == null) { + return "null"; + } + StringBuilder sb = new StringBuilder(); + for (char c : str.toCharArray()) { + sb.append(String.format("%02X ", (int) c)); + } + return sb.toString().trim(); + } + /** * 新增读取记录 *

diff --git a/ruoyi-modules/hw-rfid/src/main/resources/mapper/rfid/RfidReadRecordMapper.xml b/ruoyi-modules/hw-rfid/src/main/resources/mapper/rfid/RfidReadRecordMapper.xml index 6db5f6a..debb4ef 100644 --- a/ruoyi-modules/hw-rfid/src/main/resources/mapper/rfid/RfidReadRecordMapper.xml +++ b/ruoyi-modules/hw-rfid/src/main/resources/mapper/rfid/RfidReadRecordMapper.xml @@ -14,7 +14,7 @@ d.device_code as deviceCode, d.device_name as deviceName, t.read_status, - t.barcode, + TRIM(t.barcode) as barcode, t.record_time, t.alarm_flag, t.alarm_level, @@ -36,7 +36,7 @@ d.device_code as deviceCode, d.device_name as deviceName, combined.read_status, - combined.barcode, + TRIM(combined.barcode) as barcode, combined.record_time, combined.alarm_flag, combined.alarm_level, @@ -47,7 +47,7 @@ select t.id, t.device_id, t.read_status, - t.barcode, + TRIM(t.barcode) as barcode, t.record_time, t.alarm_flag, t.alarm_level, @@ -70,7 +70,7 @@ d.device_code as deviceCode, d.device_name as deviceName, t.read_status, - t.barcode, + TRIM(t.barcode) as barcode, t.record_time, t.alarm_flag, t.alarm_level, @@ -88,7 +88,7 @@ d.device_code as deviceCode, d.device_name as deviceName, t.read_status, - t.barcode, + TRIM(t.barcode) as barcode, t.record_time, t.alarm_flag, t.alarm_level, @@ -131,7 +131,7 @@ d.device_code as deviceCode, d.device_name as deviceName, t.read_status, - t.barcode, + TRIM(t.barcode) as barcode, t.record_time, t.alarm_flag, t.alarm_level, @@ -153,7 +153,7 @@ d.device_code as deviceCode, d.device_name as deviceName, combined.read_status, - combined.barcode, + TRIM(combined.barcode) as barcode, combined.record_time, combined.alarm_flag, combined.alarm_level, @@ -164,7 +164,7 @@ select t.id, t.device_id, t.read_status, - t.barcode, + TRIM(t.barcode) as barcode, t.record_time, t.alarm_flag, t.alarm_level, @@ -355,7 +355,7 @@ d.device_code as deviceCode, d.device_name as deviceName, t.read_status, - t.barcode, + TRIM(t.barcode) as barcode, t.record_time, t.alarm_flag, t.alarm_level, @@ -400,7 +400,7 @@ d.device_name as deviceName, l.location_alias as locationAlias, t.read_status, - t.barcode, + TRIM(t.barcode) as barcode, t.record_time, t.alarm_flag, t.alarm_level, @@ -425,7 +425,7 @@ d.device_code as deviceCode, d.device_name as deviceName, t1.read_status, - t1.barcode, + TRIM(t1.barcode) as barcode, t1.record_time, t1.alarm_flag, t1.alarm_level, @@ -456,7 +456,7 @@ d.device_code as deviceCode, d.device_name as deviceName, sampled.read_status, - sampled.barcode, + TRIM(sampled.barcode) as barcode, sampled.record_time, sampled.alarm_flag, sampled.alarm_level, @@ -467,7 +467,7 @@ select t1.id, t1.device_id, t1.read_status, - t1.barcode, + TRIM(t1.barcode) as barcode, t1.record_time, t1.alarm_flag, t1.alarm_level,