| | |
| | | import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.mes.framework.collect.config.MesCollectProperties; |
| | | import java.time.Duration; |
| | | import java.util.ArrayList; |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | |
| | | private MesCollectTaskResolver taskResolver; |
| | | @Resource |
| | | private MesMdWorkstationService workstationService; |
| | | @Resource |
| | | private MesCollectProperties collectProperties; |
| | | |
| | | /** 基于保留的数采历史计算离线区间,首次采样之前不作推断。 */ |
| | | public MesCollectOfflineResultRespVO getOfflineIntervals(String deviceCode, LocalDateTime start, LocalDateTime end) { |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | if (deviceCode == null || deviceCode.isBlank() || start == null || end == null || !start.isBefore(end) |
| | | || end.isAfter(now) || Duration.between(start, end).compareTo(Duration.ofDays(7)) > 0) { |
| | | throw invalidParamException("请选择有效的设备和时间范围,单次最多查询七天,结束时间不能晚于当前时间"); |
| | | } |
| | | if (start.isBefore(now.minusDays(collectProperties.getRetention().getRealtimeDays()))) { |
| | | throw invalidParamException("查询时间超出数采历史保留期,无法可靠计算停机记录"); |
| | | } |
| | | var prior = realtimeHistoryMapper.selectOne(new LambdaQueryWrapperX<MesCollectRealtimeHistoryDO>() |
| | | .eq(MesCollectRealtimeHistoryDO::getDeviceCode, deviceCode) |
| | | .ge(MesCollectRealtimeHistoryDO::getCollectTime, now.minusDays(collectProperties.getRetention().getRealtimeDays())) |
| | | .le(MesCollectRealtimeHistoryDO::getCollectTime, start) |
| | | .orderByDesc(MesCollectRealtimeHistoryDO::getCollectTime).last("LIMIT 1")); |
| | | var history = realtimeHistoryMapper.selectList(new LambdaQueryWrapperX<MesCollectRealtimeHistoryDO>() |
| | | .eq(MesCollectRealtimeHistoryDO::getDeviceCode, deviceCode) |
| | | .gt(MesCollectRealtimeHistoryDO::getCollectTime, start) |
| | | .le(MesCollectRealtimeHistoryDO::getCollectTime, end) |
| | | .orderByAsc(MesCollectRealtimeHistoryDO::getCollectTime).last("LIMIT 100001")); |
| | | if (history.size() > 100000) throw invalidParamException("采样数据过多,请缩短查询时间范围"); |
| | | List<LocalDateTime> samples = new ArrayList<>(); |
| | | if (prior != null) samples.add(prior.getCollectTime()); |
| | | history.forEach(item -> samples.add(item.getCollectTime())); |
| | | var intervals = CollectOfflinePolicy.calculate(samples, start, end, Duration.ofMinutes(ONLINE_TIMEOUT_MINUTES)).stream() |
| | | .map(item -> new MesCollectOfflineIntervalRespVO(item.start(), item.end(), Duration.between(item.start(), item.end()).getSeconds())) |
| | | .toList(); |
| | | return new MesCollectOfflineResultRespVO(samples.isEmpty() ? null : samples.getFirst(), intervals); |
| | | } |
| | | |
| | | /** |
| | | * 获取已配置数采编码的设备实时状态列表 |