|
@@ -11,6 +11,7 @@ import com.hdkj.lt.bf.common.SeSnapshotConstants;
|
|
|
import com.hdkj.lt.bf.entity.DwdShbDsTransformerBase;
|
|
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.FhzgSeLineLossRate;
|
|
import com.hdkj.lt.bf.entity.FhzgSeLineLossRate;
|
|
|
|
|
+import com.hdkj.lt.bf.entity.FhzgSeSegmentPqui;
|
|
|
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;
|
|
|
import com.hdkj.lt.bf.entity.FhzgSeSnapshotDetail;
|
|
import com.hdkj.lt.bf.entity.FhzgSeSnapshotDetail;
|
|
@@ -20,6 +21,7 @@ import com.hdkj.lt.bf.event.ReconTriggerEvent;
|
|
|
import com.hdkj.lt.bf.mapper.FeederTopoMapper;
|
|
import com.hdkj.lt.bf.mapper.FeederTopoMapper;
|
|
|
import com.hdkj.lt.bf.mapper.FhzgSeCurrentEventMapper;
|
|
import com.hdkj.lt.bf.mapper.FhzgSeCurrentEventMapper;
|
|
|
import com.hdkj.lt.bf.mapper.FhzgSeLineLossRateMapper;
|
|
import com.hdkj.lt.bf.mapper.FhzgSeLineLossRateMapper;
|
|
|
|
|
+import com.hdkj.lt.bf.mapper.FhzgSeSegmentPquiMapper;
|
|
|
import com.hdkj.lt.bf.mapper.FhzgSeMonitorCurrentMapper;
|
|
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;
|
|
@@ -56,6 +58,7 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
private final ApplicationEventPublisher eventPublisher;
|
|
private final ApplicationEventPublisher eventPublisher;
|
|
|
private final FeederTopoMapper feederTopoMapper;
|
|
private final FeederTopoMapper feederTopoMapper;
|
|
|
private final FhzgSeLineLossRateMapper lineLossRateMapper;
|
|
private final FhzgSeLineLossRateMapper lineLossRateMapper;
|
|
|
|
|
+ private final FhzgSeSegmentPquiMapper segmentPquiMapper;
|
|
|
|
|
|
|
|
private static final DateTimeFormatter DT_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
private static final DateTimeFormatter DT_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
|
|
@@ -169,6 +172,10 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
// 总功率=馈线块 seoPs(≈出线开关功率);配变块=0302+0110;中压用户接入点块=370000
|
|
// 总功率=馈线块 seoPs(≈出线开关功率);配变块=0302+0110;中压用户接入点块=370000
|
|
|
processLineLossRate(root, snapTime, feederMap, advanceState);
|
|
processLineLossRate(root, snapTime, feederMap, advanceState);
|
|
|
|
|
|
|
|
|
|
+ // === 4. 段 PQUI 明细(0201 电缆段 + dxd 导线段,首端取值)===
|
|
|
|
|
+ // P=seoPfs Q=seoQfs U=headUs I=seoIs;每断面每段一行 → fhzg_se_segment_pqui
|
|
|
|
|
+ processSegmentPqui(root, snapTime, feederMap);
|
|
|
|
|
+
|
|
|
if (!batch.isEmpty()) {
|
|
if (!batch.isEmpty()) {
|
|
|
// 防重:查该断面时刻已有的所有 device_id(精确到秒,无需再 IN 过滤)
|
|
// 防重:查该断面时刻已有的所有 device_id(精确到秒,无需再 IN 过滤)
|
|
|
Set<String> existingIds = new HashSet<>();
|
|
Set<String> existingIds = new HashSet<>();
|
|
@@ -637,8 +644,84 @@ public class SeSnapshotServiceImpl implements SeSnapshotService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 段 PQUI 明细入库:periodSegmentSeResult(0201 电缆段 + dxd 导线段)
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * 取数:P=seoPfs(首端有功)、Q=seoQfs(首端无功)、U=headUs(首端电压)、I=seoIs(电流)。
|
|
|
|
|
+ * 每断面每段一行写 fhzg_se_segment_pqui;段数据只有 feederId,subs/county 由 feederMap 带出。
|
|
|
|
|
+ * 防重:查该断面时刻已有的 segment_id(避免重复跑同一断面时叠加)。
|
|
|
|
|
+ */
|
|
|
|
|
+ private void processSegmentPqui(JSONObject root, LocalDateTime snapTime,
|
|
|
|
|
+ Map<String, String[]> feederMap) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ JSONArray segments = root.getJSONArray("periodSegmentSeResult");
|
|
|
|
|
+ if (segments == null || segments.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ List<FhzgSeSegmentPqui> batch = new ArrayList<>();
|
|
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
+ for (int i = 0; i < segments.size(); i++) {
|
|
|
|
|
+ JSONObject s = segments.getJSONObject(i);
|
|
|
|
|
+ String segmentId = s.getString("psrId");
|
|
|
|
|
+ if (segmentId == null || segmentId.isEmpty()) continue;
|
|
|
|
|
+ String feederId = s.getString("feederId");
|
|
|
|
|
+ if (feederId == null || feederId.isEmpty()) continue;
|
|
|
|
|
+
|
|
|
|
|
+ BigDecimal p = firstValue(s.getJSONArray("seoPfs"));
|
|
|
|
|
+ BigDecimal q = firstValue(s.getJSONArray("seoQfs"));
|
|
|
|
|
+ BigDecimal u = firstValue(s.getJSONArray("headUs"));
|
|
|
|
|
+ BigDecimal cur = firstValue(s.getJSONArray("seoIs"));
|
|
|
|
|
+ if (p == null && q == null && u == null && cur == null) continue;
|
|
|
|
|
+
|
|
|
|
|
+ String[] loc = feederMap.getOrDefault(feederId, new String[]{"", "", ""});
|
|
|
|
|
+ batch.add(FhzgSeSegmentPqui.builder()
|
|
|
|
|
+ .snapTime(snapTime)
|
|
|
|
|
+ .segmentId(segmentId)
|
|
|
|
|
+ .psrType(s.getString("psrType"))
|
|
|
|
|
+ .feederId(feederId)
|
|
|
|
|
+ .subsId(loc.length > 0 ? loc[0] : "")
|
|
|
|
|
+ .countyId(loc.length > 1 ? loc[1] : "")
|
|
|
|
|
+ .pValue(p)
|
|
|
|
|
+ .qValue(q)
|
|
|
|
|
+ .uValue(u)
|
|
|
|
|
+ .iValue(cur)
|
|
|
|
|
+ .createTime(now)
|
|
|
|
|
+ .build());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!batch.isEmpty()) {
|
|
|
|
|
+ // 防重:查该断面时刻已有的段(避免重复跑同一断面时叠加)
|
|
|
|
|
+ Set<String> existingSegmentIds = new HashSet<>();
|
|
|
|
|
+ segmentPquiMapper.selectList(
|
|
|
|
|
+ new LambdaQueryWrapper<FhzgSeSegmentPqui>()
|
|
|
|
|
+ .select(FhzgSeSegmentPqui::getSegmentId)
|
|
|
|
|
+ .eq(FhzgSeSegmentPqui::getSnapTime, snapTime)
|
|
|
|
|
+ ).forEach(e -> existingSegmentIds.add(e.getSegmentId()));
|
|
|
|
|
+
|
|
|
|
|
+ List<FhzgSeSegmentPqui> toInsert = new ArrayList<>();
|
|
|
|
|
+ for (FhzgSeSegmentPqui d : batch) {
|
|
|
|
|
+ if (existingSegmentIds.contains(d.getSegmentId())) continue;
|
|
|
|
|
+ toInsert.add(d);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int inserted = 0;
|
|
|
|
|
+ if (!toInsert.isEmpty()) {
|
|
|
|
|
+ inserted = insertBatchSharded(rows -> {
|
|
|
|
|
+ toInsert.forEach(segmentPquiMapper::insert);
|
|
|
|
|
+ return toInsert.size();
|
|
|
|
|
+ }, toInsert);
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("段PQUI明细入库完成 snapTime={}, 写入{}条, 跳过{}条(无数据{}条/重复{}条)",
|
|
|
|
|
+ snapTime, inserted, batch.size() - inserted,
|
|
|
|
|
+ batch.size() - toInsert.size(), existingSegmentIds.size());
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("段PQUI明细入库失败 snapTime={}", snapTime, e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// ============================================================
|
|
// ============================================================
|
|
|
- // 查询辅助
|
|
|
|
|
|
|
+
|
|
|
// ============================================================
|
|
// ============================================================
|
|
|
|
|
|
|
|
/**
|
|
/**
|