package com.ruoyi.system.service.impl; import java.time.Instant; import java.util.Collections; import java.util.Set; import java.util.stream.Collectors; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.alibaba.fastjson2.JSON; import com.ruoyi.system.domain.TTestCollectorExceptionInterval; import com.ruoyi.system.domain.TTestCollectorSource; import com.ruoyi.system.mapper.TTestMapper; import com.ruoyi.system.service.ICollectorDisconnectRecoveryService; /** 将采集器在线事实对账为可恢复的来源级异常区间。 */ public class CollectorDisconnectRecoveryServiceImpl implements ICollectorDisconnectRecoveryService { private final TTestMapper mapper; public CollectorDisconnectRecoveryServiceImpl(TTestMapper mapper) { this.mapper = mapper; } @Override @Transactional(rollbackFor = Exception.class) public void reconcile(Set onlineCollectorCodes, Instant observedAt) { Set online = onlineCollectorCodes == null ? Collections.emptySet() : onlineCollectorCodes.stream().filter(code -> code != null && !code.isBlank()).collect(Collectors.toSet()); for (TTestCollectorSource source : mapper.selectReceivingCollectorSources()) { TTestCollectorExceptionInterval open = mapper.selectOpenCollectorException(source.getTestId(), source.getBatteryRelationId(), source.getCollectorId(), source.getChannelCode()); boolean isOnline = online.contains(source.getCollectorCode()); if (!isOnline && open == null) { TTestCollectorExceptionInterval interval = new TTestCollectorExceptionInterval(); interval.setTestId(source.getTestId()); interval.setBatteryRelationId(source.getBatteryRelationId()); interval.setCollectorId(source.getCollectorId()); interval.setCollectorChannelCode(source.getChannelCode()); interval.setExceptionType("COLLECTOR_DISCONNECTED"); java.util.Date at = java.util.Date.from(observedAt); interval.setOpenedAtUtc(at); interval.setMissingFromUtc(at); interval.setDetail(JSON.toJSONString(java.util.Map.of("batteryNo", source.getBatteryNo(), "collectorCode", source.getCollectorCode(), "message", "采集器离线,检测柜及其他来源继续接收"))); mapper.insertCollectorExceptionInterval(interval); mapper.insertTestAudit(source.getTestId(), "COLLECTOR_DISCONNECTED", null, "system", null, JSON.toJSONString(java.util.Map.of("collectorId", source.getCollectorId(), "channelCode", source.getChannelCode(), "missingFrom", observedAt.toString()))); } else if (isOnline && open != null) { java.util.Date at = java.util.Date.from(observedAt); mapper.closeCollectorExceptionInterval(open.getIntervalId(), at, at); mapper.insertTestAudit(source.getTestId(), "COLLECTOR_RECONNECTED", null, "system", null, JSON.toJSONString(java.util.Map.of("collectorId", source.getCollectorId(), "channelCode", source.getChannelCode(), "recoveredAt", observedAt.toString()))); } } } }