|
@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.hdkj.lt.bf.application.FeederGroupApplication;
|
|
import com.hdkj.lt.bf.application.FeederGroupApplication;
|
|
|
import com.hdkj.lt.bf.common.SeMonitorThreshold;
|
|
import com.hdkj.lt.bf.common.SeMonitorThreshold;
|
|
|
import com.hdkj.lt.bf.common.SeSnapshotConstants;
|
|
import com.hdkj.lt.bf.common.SeSnapshotConstants;
|
|
|
|
|
+import com.hdkj.lt.bf.entity.DwdShbDsTransformerBase;
|
|
|
import com.hdkj.lt.bf.entity.FhzgSeCurrentEvent;
|
|
import com.hdkj.lt.bf.entity.FhzgSeCurrentEvent;
|
|
|
import com.hdkj.lt.bf.entity.FhzgSeMonitorCurrent;
|
|
import com.hdkj.lt.bf.entity.FhzgSeMonitorCurrent;
|
|
|
import com.hdkj.lt.bf.entity.FhzgSeMonitorVoltage;
|
|
import com.hdkj.lt.bf.entity.FhzgSeMonitorVoltage;
|
|
@@ -19,6 +20,7 @@ import com.hdkj.lt.bf.mapper.FhzgSeMonitorCurrentMapper;
|
|
|
import com.hdkj.lt.bf.mapper.FhzgSeMonitorVoltageMapper;
|
|
import com.hdkj.lt.bf.mapper.FhzgSeMonitorVoltageMapper;
|
|
|
import com.hdkj.lt.bf.mapper.FhzgSeSnapshotDetailMapper;
|
|
import com.hdkj.lt.bf.mapper.FhzgSeSnapshotDetailMapper;
|
|
|
import com.hdkj.lt.bf.mapper.FhzgSeVoltageEventMapper;
|
|
import com.hdkj.lt.bf.mapper.FhzgSeVoltageEventMapper;
|
|
|
|
|
+import com.hdkj.lt.bf.mapper.DwdShbDsTransformerBaseMapper;
|
|
|
import com.hdkj.lt.bf.service.SeSnapshotService;
|
|
import com.hdkj.lt.bf.service.SeSnapshotService;
|
|
|
import com.hdkj.fhzg.optimization.response.FeederGroupTreeNode;
|
|
import com.hdkj.fhzg.optimization.response.FeederGroupTreeNode;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
@@ -44,6 +46,7 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
private final FhzgSeMonitorVoltageMapper monitorVoltageMapper;
|
|
private final FhzgSeMonitorVoltageMapper monitorVoltageMapper;
|
|
|
private final FhzgSeCurrentEventMapper currentEventMapper;
|
|
private final FhzgSeCurrentEventMapper currentEventMapper;
|
|
|
private final FhzgSeVoltageEventMapper voltageEventMapper;
|
|
private final FhzgSeVoltageEventMapper voltageEventMapper;
|
|
|
|
|
+ private final DwdShbDsTransformerBaseMapper transformerBaseMapper;
|
|
|
private final FeederGroupApplication feederGroupApplication;
|
|
private final FeederGroupApplication feederGroupApplication;
|
|
|
private final ApplicationEventPublisher eventPublisher;
|
|
private final ApplicationEventPublisher eventPublisher;
|
|
|
|
|
|
|
@@ -87,13 +90,21 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
|
|
|
|
|
// === 2. 配变 ===
|
|
// === 2. 配变 ===
|
|
|
JSONArray mvtrans = root.getJSONArray("periodMVTransSeResult");
|
|
JSONArray mvtrans = root.getJSONArray("periodMVTransSeResult");
|
|
|
- if (mvtrans != null) {
|
|
|
|
|
|
|
+ Map<String, String> transformerNameMap = new HashMap<>();
|
|
|
|
|
+ if (mvtrans != null && !mvtrans.isEmpty()) {
|
|
|
|
|
+ // 先收集当前断面所有配变 ID,再一次性查名称(避免全表加载)
|
|
|
|
|
+ Set<String> mvtransIds = new HashSet<>();
|
|
|
|
|
+ for (int i = 0; i < mvtrans.size(); i++) {
|
|
|
|
|
+ String id = mvtrans.getJSONObject(i).getString("psrId");
|
|
|
|
|
+ if (id != null) mvtransIds.add(id);
|
|
|
|
|
+ }
|
|
|
|
|
+ transformerNameMap = buildTransformerMapping(mvtransIds);
|
|
|
for (int i = 0; i < mvtrans.size(); i++) {
|
|
for (int i = 0; i < mvtrans.size(); i++) {
|
|
|
JSONObject m = mvtrans.getJSONObject(i);
|
|
JSONObject m = mvtrans.getJSONObject(i);
|
|
|
FhzgSeSnapshotDetail d = parseMvtrans(m, snapTime, feederMap);
|
|
FhzgSeSnapshotDetail d = parseMvtrans(m, snapTime, feederMap);
|
|
|
if (d != null) {
|
|
if (d != null) {
|
|
|
batch.add(d);
|
|
batch.add(d);
|
|
|
- processMvtransMonitor(m, d, snapTime, feederMap);
|
|
|
|
|
|
|
+ processMvtransMonitor(m, d, snapTime, feederMap, transformerNameMap);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -168,6 +179,15 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
} else {
|
|
} else {
|
|
|
LocalDateTime lastSnap = state.getLastSnapTime();
|
|
LocalDateTime lastSnap = state.getLastSnapTime();
|
|
|
if (lastSnap != null && Duration.between(lastSnap, snapTime).toMinutes() > SeMonitorThreshold.SNAP_INTERVAL_MINUTES) {
|
|
if (lastSnap != null && Duration.between(lastSnap, snapTime).toMinutes() > SeMonitorThreshold.SNAP_INTERVAL_MINUTES) {
|
|
|
|
|
+ // 断档间隙:先关掉还在活跃的事件,再清空状态机引用
|
|
|
|
|
+ if (state.getAlarmTriggered() == 1 && state.getAlarmEventId() != null) {
|
|
|
|
|
+ FhzgSeCurrentEvent close = new FhzgSeCurrentEvent();
|
|
|
|
|
+ close.setId(state.getAlarmEventId());
|
|
|
|
|
+ close.setStatus(2);
|
|
|
|
|
+ close.setRecoverTime(snapTime);
|
|
|
|
|
+ close.setLastLoadRate(loadRate);
|
|
|
|
|
+ currentEventMapper.updateById(close);
|
|
|
|
|
+ }
|
|
|
state.setFirstOverTime(null);
|
|
state.setFirstOverTime(null);
|
|
|
state.setAlarmTriggered(0);
|
|
state.setAlarmTriggered(0);
|
|
|
state.setAlarmEventId(null);
|
|
state.setAlarmEventId(null);
|
|
@@ -194,18 +214,39 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
currentEventMapper.insert(event);
|
|
currentEventMapper.insert(event);
|
|
|
state.setAlarmTriggered(1);
|
|
state.setAlarmTriggered(1);
|
|
|
state.setAlarmEventId(event.getId());
|
|
state.setAlarmEventId(event.getId());
|
|
|
- // 异步触发重构算法(需要 feeder_id + point_time)
|
|
|
|
|
|
|
+ // 取事件窗口内最大负载率断面时刻作为重构触发断面时刻
|
|
|
|
|
+ LocalDateTime maxLrTime = findMaxLoadRateTime(feederId, state.getFirstOverTime(), snapTime);
|
|
|
eventPublisher.publishEvent(new ReconTriggerEvent(
|
|
eventPublisher.publishEvent(new ReconTriggerEvent(
|
|
|
event.getId(), feederId, feederName, countyId, subsId,
|
|
event.getId(), feederId, feederName, countyId, subsId,
|
|
|
- alarmType, snapTime, state.getFirstOverTime()));
|
|
|
|
|
|
|
+ alarmType, maxLrTime, state.getFirstOverTime()));
|
|
|
|
|
+ }
|
|
|
|
|
+ // 活跃事件:断面负载率比记录值高则刷新 maxLoadRate
|
|
|
|
|
+ if (state.getAlarmTriggered() == 1 && state.getAlarmEventId() != null) {
|
|
|
|
|
+ FhzgSeCurrentEvent cur = currentEventMapper.selectById(state.getAlarmEventId());
|
|
|
|
|
+ if (cur != null) {
|
|
|
|
|
+ BigDecimal curMax = cur.getMaxLoadRate();
|
|
|
|
|
+ if (loadRate != null && (curMax == null || loadRate.compareTo(curMax) > 0)) {
|
|
|
|
|
+ FhzgSeCurrentEvent upd = new FhzgSeCurrentEvent();
|
|
|
|
|
+ upd.setId(state.getAlarmEventId());
|
|
|
|
|
+ upd.setMaxLoadRate(loadRate);
|
|
|
|
|
+ currentEventMapper.updateById(upd);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
if (state.getAlarmTriggered() == 1 && state.getAlarmEventId() != null) {
|
|
if (state.getAlarmTriggered() == 1 && state.getAlarmEventId() != null) {
|
|
|
- FhzgSeCurrentEvent update = new FhzgSeCurrentEvent();
|
|
|
|
|
- update.setId(state.getAlarmEventId());
|
|
|
|
|
- update.setStatus(2); update.setRecoverTime(snapTime);
|
|
|
|
|
- update.setLastLoadRate(loadRate); update.setMaxLoadRate(maxLoadRate);
|
|
|
|
|
- currentEventMapper.updateById(update);
|
|
|
|
|
|
|
+ FhzgSeCurrentEvent cur = currentEventMapper.selectById(state.getAlarmEventId());
|
|
|
|
|
+ if (cur != null) {
|
|
|
|
|
+ BigDecimal trueMax = cur.getMaxLoadRate();
|
|
|
|
|
+ if (trueMax == null || (maxLoadRate != null && maxLoadRate.compareTo(trueMax) > 0)) {
|
|
|
|
|
+ trueMax = maxLoadRate;
|
|
|
|
|
+ }
|
|
|
|
|
+ FhzgSeCurrentEvent update = new FhzgSeCurrentEvent();
|
|
|
|
|
+ update.setId(state.getAlarmEventId());
|
|
|
|
|
+ update.setStatus(2); update.setRecoverTime(snapTime);
|
|
|
|
|
+ update.setLastLoadRate(loadRate); update.setMaxLoadRate(trueMax);
|
|
|
|
|
+ currentEventMapper.updateById(update);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
state.setFirstOverTime(null); state.setAlarmTriggered(0); state.setAlarmEventId(null);
|
|
state.setFirstOverTime(null); state.setAlarmTriggered(0); state.setAlarmEventId(null);
|
|
|
}
|
|
}
|
|
@@ -218,8 +259,9 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
LocalDateTime snapTime, Map<String, String[]> feederMap) {
|
|
LocalDateTime snapTime, Map<String, String[]> feederMap) {
|
|
|
if (detail.getVoltageStatus() == null) return;
|
|
if (detail.getVoltageStatus() == null) return;
|
|
|
String[] loc = feederMap.get(detail.getFeederId());
|
|
String[] loc = feederMap.get(detail.getFeederId());
|
|
|
- checkVoltageMonitor(detail.getFeederId(), "feeder", detail.getVoltageRatio(), detail.getVoltageStatus(),
|
|
|
|
|
- snapTime, detail.getFeederId(), loc != null && loc.length > 2 ? loc[2] : null,
|
|
|
|
|
|
|
+ String feederName = loc != null && loc.length > 2 ? loc[2] : null;
|
|
|
|
|
+ checkVoltageMonitor(detail.getFeederId(), "feeder", feederName, detail.getVoltageRatio(), detail.getVoltageStatus(),
|
|
|
|
|
+ snapTime, detail.getFeederId(), feederName,
|
|
|
loc != null ? loc[0] : "", loc != null ? loc[1] : "", null, null);
|
|
loc != null ? loc[0] : "", loc != null ? loc[1] : "", null, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -246,14 +288,17 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void processMvtransMonitor(JSONObject m, FhzgSeSnapshotDetail detail,
|
|
private void processMvtransMonitor(JSONObject m, FhzgSeSnapshotDetail detail,
|
|
|
- LocalDateTime snapTime, Map<String, String[]> feederMap) {
|
|
|
|
|
|
|
+ LocalDateTime snapTime, Map<String, String[]> feederMap,
|
|
|
|
|
+ Map<String, String> transformerNameMap) {
|
|
|
if (detail.getVoltageStatus() == null) return;
|
|
if (detail.getVoltageStatus() == null) return;
|
|
|
String mvtransId = detail.getDeviceId();
|
|
String mvtransId = detail.getDeviceId();
|
|
|
String[] loc = feederMap.get(detail.getFeederId());
|
|
String[] loc = feederMap.get(detail.getFeederId());
|
|
|
int status = detail.getVoltageStatus();
|
|
int status = detail.getVoltageStatus();
|
|
|
if (status == 0) recoverUserAlarms(mvtransId, snapTime);
|
|
if (status == 0) recoverUserAlarms(mvtransId, snapTime);
|
|
|
|
|
|
|
|
- checkVoltageMonitor(mvtransId, "mvtrans", detail.getVoltageRatio(), status,
|
|
|
|
|
|
|
+ String transformerName = transformerNameMap != null
|
|
|
|
|
+ ? transformerNameMap.getOrDefault(mvtransId, mvtransId) : mvtransId;
|
|
|
|
|
+ checkVoltageMonitor(mvtransId, "mvtrans", transformerName, detail.getVoltageRatio(), status,
|
|
|
snapTime, detail.getFeederId(), loc != null && loc.length > 2 ? loc[2] : null,
|
|
snapTime, detail.getFeederId(), loc != null && loc.length > 2 ? loc[2] : null,
|
|
|
loc != null ? loc[0] : "", loc != null ? loc[1] : "", mvtransId, null);
|
|
loc != null ? loc[0] : "", loc != null ? loc[1] : "", mvtransId, null);
|
|
|
|
|
|
|
@@ -269,7 +314,7 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
// 电压状态机
|
|
// 电压状态机
|
|
|
// ============================================================
|
|
// ============================================================
|
|
|
|
|
|
|
|
- private void checkVoltageMonitor(String deviceId, String deviceType,
|
|
|
|
|
|
|
+ private void checkVoltageMonitor(String deviceId, String deviceType, String deviceName,
|
|
|
BigDecimal voltageRatio, int voltageStatus,
|
|
BigDecimal voltageRatio, int voltageStatus,
|
|
|
LocalDateTime snapTime, String feederId, String feederName,
|
|
LocalDateTime snapTime, String feederId, String feederName,
|
|
|
String subsId, String countyId, String mvtransId, String consumerId) {
|
|
String subsId, String countyId, String mvtransId, String consumerId) {
|
|
@@ -292,6 +337,13 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
} else {
|
|
} else {
|
|
|
LocalDateTime lastSnap = state.getLastSnapTime();
|
|
LocalDateTime lastSnap = state.getLastSnapTime();
|
|
|
if (lastSnap != null && Duration.between(lastSnap, snapTime).toMinutes() > SeMonitorThreshold.SNAP_INTERVAL_MINUTES) {
|
|
if (lastSnap != null && Duration.between(lastSnap, snapTime).toMinutes() > SeMonitorThreshold.SNAP_INTERVAL_MINUTES) {
|
|
|
|
|
+ // 断档间隙:先关掉还在活跃的事件,再清空状态机引用
|
|
|
|
|
+ if (state.getAlarmTriggered() == 1 && state.getAlarmEventId() != null) {
|
|
|
|
|
+ FhzgSeVoltageEvent close = new FhzgSeVoltageEvent();
|
|
|
|
|
+ close.setId(state.getAlarmEventId());
|
|
|
|
|
+ close.setStatus(2); close.setRecoverTime(snapTime); close.setLastValue(voltageRatio);
|
|
|
|
|
+ voltageEventMapper.updateById(close);
|
|
|
|
|
+ }
|
|
|
state.setFirstOverTime(null); state.setAlarmTriggered(0); state.setAlarmEventId(null);
|
|
state.setFirstOverTime(null); state.setAlarmTriggered(0); state.setAlarmEventId(null);
|
|
|
}
|
|
}
|
|
|
if (isOverLimit) {
|
|
if (isOverLimit) {
|
|
@@ -308,7 +360,7 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
BigDecimal[] vr = queryVoltageRangeFromSnap(feederId, state.getFirstOverTime(), snapTime);
|
|
BigDecimal[] vr = queryVoltageRangeFromSnap(feederId, state.getFirstOverTime(), snapTime);
|
|
|
int[] mc = queryMvtransCounts(feederId, state.getFirstOverTime(), snapTime);
|
|
int[] mc = queryMvtransCounts(feederId, state.getFirstOverTime(), snapTime);
|
|
|
FhzgSeVoltageEvent event = FhzgSeVoltageEvent.builder()
|
|
FhzgSeVoltageEvent event = FhzgSeVoltageEvent.builder()
|
|
|
- .deviceId(deviceId).deviceName(feederName)
|
|
|
|
|
|
|
+ .deviceId(deviceId).deviceName(deviceName)
|
|
|
.deviceType(deviceType).alarmLevel(deviceType).alarmType(alarmType)
|
|
.deviceType(deviceType).alarmLevel(deviceType).alarmType(alarmType)
|
|
|
.feederId(feederId).feederName(feederName)
|
|
.feederId(feederId).feederName(feederName)
|
|
|
.subsId(subsId).countyId(countyId).countyName(countyName)
|
|
.subsId(subsId).countyId(countyId).countyName(countyName)
|
|
@@ -331,7 +383,7 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
String alarmType = resolveVoltageAlarmType(deviceType, voltageStatus);
|
|
String alarmType = resolveVoltageAlarmType(deviceType, voltageStatus);
|
|
|
BigDecimal threshold = resolveVoltageThreshold(deviceType, voltageStatus);
|
|
BigDecimal threshold = resolveVoltageThreshold(deviceType, voltageStatus);
|
|
|
FhzgSeVoltageEvent event = FhzgSeVoltageEvent.builder()
|
|
FhzgSeVoltageEvent event = FhzgSeVoltageEvent.builder()
|
|
|
- .deviceId(deviceId).deviceName(feederName)
|
|
|
|
|
|
|
+ .deviceId(deviceId).deviceName(deviceName)
|
|
|
.deviceType(deviceType).alarmLevel(deviceType).alarmType(alarmType)
|
|
.deviceType(deviceType).alarmLevel(deviceType).alarmType(alarmType)
|
|
|
.feederId(feederId).feederName(feederName)
|
|
.feederId(feederId).feederName(feederName)
|
|
|
.subsId(subsId).countyId(countyId).countyName(countyName)
|
|
.subsId(subsId).countyId(countyId).countyName(countyName)
|
|
@@ -347,14 +399,12 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
// consumer 级别暂走旧逻辑(如有可后续优化)
|
|
// consumer 级别暂走旧逻辑(如有可后续优化)
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
|
|
+ // 设备恢复正常(任何 deviceType 都走):关自己的事件
|
|
|
if (state.getAlarmTriggered() == 1 && state.getAlarmEventId() != null) {
|
|
if (state.getAlarmTriggered() == 1 && state.getAlarmEventId() != null) {
|
|
|
- // 只有 feeder 自身恢复才标聚合事件 status=2;mvtrans 恢复不动聚合事件
|
|
|
|
|
- if ("feeder".equals(deviceType)) {
|
|
|
|
|
- FhzgSeVoltageEvent update = new FhzgSeVoltageEvent();
|
|
|
|
|
- update.setId(state.getAlarmEventId());
|
|
|
|
|
- update.setStatus(2); update.setRecoverTime(snapTime); update.setLastValue(voltageRatio);
|
|
|
|
|
- voltageEventMapper.updateById(update);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ FhzgSeVoltageEvent update = new FhzgSeVoltageEvent();
|
|
|
|
|
+ update.setId(state.getAlarmEventId());
|
|
|
|
|
+ update.setStatus(2); update.setRecoverTime(snapTime); update.setLastValue(voltageRatio);
|
|
|
|
|
+ voltageEventMapper.updateById(update);
|
|
|
}
|
|
}
|
|
|
state.setFirstOverTime(null); state.setAlarmTriggered(0); state.setAlarmEventId(null);
|
|
state.setFirstOverTime(null); state.setAlarmTriggered(0); state.setAlarmEventId(null);
|
|
|
}
|
|
}
|
|
@@ -433,14 +483,14 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private int calcFeederVoltageStatus(BigDecimal ratio) {
|
|
private int calcFeederVoltageStatus(BigDecimal ratio) {
|
|
|
- if (ratio == null) return 0;
|
|
|
|
|
|
|
+ if (ratio == null || ratio.signum() <= 0) return 0;
|
|
|
if (ratio.compareTo(SeMonitorThreshold.FEEDER_V_OVER) > 0) return 1;
|
|
if (ratio.compareTo(SeMonitorThreshold.FEEDER_V_OVER) > 0) return 1;
|
|
|
if (ratio.compareTo(SeMonitorThreshold.FEEDER_V_UNDER) < 0) return 2;
|
|
if (ratio.compareTo(SeMonitorThreshold.FEEDER_V_UNDER) < 0) return 2;
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private int calcMvtransVoltageStatus(BigDecimal ratio) {
|
|
private int calcMvtransVoltageStatus(BigDecimal ratio) {
|
|
|
- if (ratio == null) return 0;
|
|
|
|
|
|
|
+ if (ratio == null || ratio.signum() <= 0) return 0;
|
|
|
if (ratio.compareTo(SeMonitorThreshold.MVTRANS_V_OVER) > 0) return 1;
|
|
if (ratio.compareTo(SeMonitorThreshold.MVTRANS_V_OVER) > 0) return 1;
|
|
|
if (ratio.compareTo(SeMonitorThreshold.MVTRANS_V_UNDER) < 0) return 2;
|
|
if (ratio.compareTo(SeMonitorThreshold.MVTRANS_V_UNDER) < 0) return 2;
|
|
|
return 0;
|
|
return 0;
|
|
@@ -501,6 +551,26 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
try { return new BigDecimal(v); } catch (NumberFormatException e) { return null; }
|
|
try { return new BigDecimal(v); } catch (NumberFormatException e) { return null; }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 查事件窗口 [start, end] 内该馈线最大负载率的那条断面的 snapshotTime
|
|
|
|
|
+ */
|
|
|
|
|
+ private LocalDateTime findMaxLoadRateTime(String feederId, LocalDateTime start, LocalDateTime end) {
|
|
|
|
|
+ if (feederId == null || start == null) return end;
|
|
|
|
|
+ List<FhzgSeSnapshotDetail> list = snapshotDetailMapper.selectList(
|
|
|
|
|
+ new LambdaQueryWrapper<FhzgSeSnapshotDetail>()
|
|
|
|
|
+ .eq(FhzgSeSnapshotDetail::getFeederId, feederId)
|
|
|
|
|
+ .eq(FhzgSeSnapshotDetail::getDeviceType, "feeder")
|
|
|
|
|
+ .isNotNull(FhzgSeSnapshotDetail::getLoadRate)
|
|
|
|
|
+ .ge(FhzgSeSnapshotDetail::getSnapshotTime, start)
|
|
|
|
|
+ .le(FhzgSeSnapshotDetail::getSnapshotTime, end != null ? end : LocalDateTime.now())
|
|
|
|
|
+ .orderByDesc(FhzgSeSnapshotDetail::getLoadRate)
|
|
|
|
|
+ .last("LIMIT 1"));
|
|
|
|
|
+ if (list != null && !list.isEmpty()) {
|
|
|
|
|
+ return list.get(0).getSnapshotTime();
|
|
|
|
|
+ }
|
|
|
|
|
+ return end;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 按 countyId 从 SeSnapshotConstants.COUNTIES 查 countyName。
|
|
* 按 countyId 从 SeSnapshotConstants.COUNTIES 查 countyName。
|
|
|
* COUNTIES 的 key=countyId(=maintOrg UUID),value=[countySid, countyName]
|
|
* COUNTIES 的 key=countyId(=maintOrg UUID),value=[countySid, countyName]
|
|
@@ -526,6 +596,29 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
return map;
|
|
return map;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 按配变 ID 集合批量查名称(只查当前断面出现的,不加载全表)
|
|
|
|
|
+ * 查不到的设备以 ID 代替
|
|
|
|
|
+ */
|
|
|
|
|
+ private Map<String, String> buildTransformerMapping(Collection<String> ids) {
|
|
|
|
|
+ if (ids == null || ids.isEmpty()) return Collections.emptyMap();
|
|
|
|
|
+ Map<String, String> map = new HashMap<>();
|
|
|
|
|
+ try {
|
|
|
|
|
+ List<DwdShbDsTransformerBase> rows = transformerBaseMapper.selectList(
|
|
|
|
|
+ new LambdaQueryWrapper<DwdShbDsTransformerBase>()
|
|
|
|
|
+ .in(DwdShbDsTransformerBase::getPsrId, ids)
|
|
|
|
|
+ .isNotNull(DwdShbDsTransformerBase::getName));
|
|
|
|
|
+ for (DwdShbDsTransformerBase row : rows) {
|
|
|
|
|
+ map.put(row.getPsrId(), row.getName());
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("配变名称映射加载完成: 配变{}台, 命中{}条, 未命中{}条",
|
|
|
|
|
+ ids.size(), map.size(), ids.size() - map.size());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("加载配变名称映射失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ return map;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private void buildFeederMappingRecursive(List<FeederGroupTreeNode> nodes, Map<String, String[]> map,
|
|
private void buildFeederMappingRecursive(List<FeederGroupTreeNode> nodes, Map<String, String[]> map,
|
|
|
String parentSubsId, String parentCountyId) {
|
|
String parentSubsId, String parentCountyId) {
|
|
|
if (nodes == null) return;
|
|
if (nodes == null) return;
|