yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/telemetry/MesDvTelemetryMapper.java
@@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.dv.telemetry.MesDvTelemetryDO; import org.apache.ibatis.annotations.Mapper; import java.time.LocalDateTime; import java.util.List; /** @@ -26,6 +27,7 @@ .eqIfPresent(MesDvTelemetryDO::getWhetherAnomaly, reqVO.getWhetherAnomaly()) .eqIfPresent(MesDvTelemetryDO::getShiftName, reqVO.getShiftName()) .betweenIfPresent(MesDvTelemetryDO::getTelemetryDataTime, reqVO.getTelemetryDataTime()) .le(MesDvTelemetryDO::getTelemetryDataTime, LocalDateTime.now().plusMinutes(5)) .orderByDesc(MesDvTelemetryDO::getTelemetryDataTime) .orderByDesc(MesDvTelemetryDO::getId)); } @@ -34,6 +36,7 @@ return selectList(new LambdaQueryWrapperX<MesDvTelemetryDO>() .eqIfPresent(MesDvTelemetryDO::getTbDeviceId, reqVO.getTbDeviceId()) .likeIfPresent(MesDvTelemetryDO::getDeviceName, reqVO.getDeviceName()) .le(MesDvTelemetryDO::getTelemetryDataTime, LocalDateTime.now().plusMinutes(5)) .orderByDesc(MesDvTelemetryDO::getTelemetryDataTime) .orderByDesc(MesDvTelemetryDO::getId) .last("LIMIT " + limit)); yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/telemetry/MesDvTelemetryServiceImpl.java
@@ -38,6 +38,8 @@ @Slf4j public class MesDvTelemetryServiceImpl implements MesDvTelemetryService { static final long MAX_FUTURE_SKEW_MINUTES = 5; @Resource private MesDvTelemetryMapper telemetryMapper; @Resource @@ -53,7 +55,12 @@ // åæè¿ä¸æ¹æ°æ®ï¼æè®¾å¤+ä¿¡å·å»éä¿çææ°ï¼ç¨äºå®æ¶çæ§è§å¾ List<MesDvTelemetryDO> list = telemetryMapper.selectLatest(reqVO, 5000); Map<String, MesDvTelemetryDO> latestMap = new LinkedHashMap<>(); LocalDateTime queryTime = LocalDateTime.now(); for (MesDvTelemetryDO row : list) { // åé鲿¤ï¼å³ä½¿æ°æ®åºä¸å·²ææªæ¥æ¶é´çèæ°æ®ï¼ä¹ä¸è½ä½ä¸ºå®æ¶æ°æ®è¿å if (!isAcceptableTelemetryTime(row.getTelemetryDataTime(), queryTime)) { continue; } String key = StrUtil.blankToDefault(row.getTbDeviceId(), "") + ":" + StrUtil.blankToDefault(row.getParamKeyName(), ""); latestMap.putIfAbsent(key, row); @@ -149,10 +156,17 @@ continue; } MesDvTelemetryDO data = convert((Map<?, ?>) rowObj); if (!isAcceptableTelemetryTime(data.getTelemetryDataTime(), pullTime)) { log.warn("[pullTelemetry][忽ç¥å¼å¸¸é¥æµæ¶é´ï¼deviceId({})ï¼telemetryDataTime({})ï¼pullTime({})]", data.getTbDeviceId(), data.getTelemetryDataTime(), pullTime); continue; } data.setPullTime(pullTime); saveList.add(data); } telemetryMapper.insertBatch(saveList); if (CollUtil.isNotEmpty(saveList)) { telemetryMapper.insertBatch(saveList); } // 6. è¿åç»è®¡ result.setRecordCount(saveList.size()); result.setDeviceCount((int) saveList.stream() @@ -204,4 +218,13 @@ } } /** * 饿µæ¶é´å¿ é¡»åå¨ï¼ä¸ä¸è½ææ¾æäºæ¬æ¬¡æå/æ¥è¯¢æ¶é´ã * ä¿ç 5 åé容差ï¼å ¼å®¹è®¾å¤æ¶éä¸åºç¨æå¡å¨ä¹é´ç轻微åå·®ã */ static boolean isAcceptableTelemetryTime(LocalDateTime telemetryTime, LocalDateTime referenceTime) { return telemetryTime != null && referenceTime != null && !telemetryTime.isAfter(referenceTime.plusMinutes(MAX_FUTURE_SKEW_MINUTES)); } } yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/dv/telemetry/MesDvTelemetryServiceImplTest.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,30 @@ package cn.iocoder.yudao.module.mes.service.dv.telemetry; import org.junit.jupiter.api.Test; import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; class MesDvTelemetryServiceImplTest { private static final LocalDateTime REFERENCE_TIME = LocalDateTime.of(2026, 11, 7, 15, 30); @Test void isAcceptableTelemetryTime_acceptsCurrentTimeAndClockSkew() { assertTrue(MesDvTelemetryServiceImpl.isAcceptableTelemetryTime(REFERENCE_TIME, REFERENCE_TIME)); assertTrue(MesDvTelemetryServiceImpl.isAcceptableTelemetryTime( REFERENCE_TIME.plusMinutes(5), REFERENCE_TIME)); } @Test void isAcceptableTelemetryTime_rejectsMissingAndFutureTime() { assertFalse(MesDvTelemetryServiceImpl.isAcceptableTelemetryTime(null, REFERENCE_TIME)); assertFalse(MesDvTelemetryServiceImpl.isAcceptableTelemetryTime( LocalDateTime.of(2026, 12, 24, 0, 0), REFERENCE_TIME)); assertFalse(MesDvTelemetryServiceImpl.isAcceptableTelemetryTime( REFERENCE_TIME.plusMinutes(5).plusNanos(1), REFERENCE_TIME)); } }