Forráskód Böngészése

重构方案出参结构调整

liuaini 2 hete
szülő
commit
1efdd7e86f

+ 34 - 24
api/load-transfer-si-api/src/main/java/com/hdkj/lt/modle/dto/recon/RawResultDTO.java

@@ -2,12 +2,21 @@ package com.hdkj.lt.modle.dto.recon;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.JsonNode;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.util.List;
+
 /**
- * 算法响应 raw_result 对象 (字段表 L0 全部字段).
- * 注意: 源 JSON 命名混合 snake_case / camelCase / PascalCase, 逐字段用 @JsonProperty 对齐.
+ * 算法响应 raw_result 对象.
+ * <p>
+ * [FHZG-RECON-MULTI] 结构变更: raw_result 现含共享标量(group_id/group_sid/group_name/
+ * st_area_id/status/algo/computeResult/detalDesc) + reconfiguration_schemes.list (多方案)。
+ * 原 SwitchOp / switchSeq / feederResult / volResult / switchResult / finalCheck / metrics
+ * 已下移到每个 scheme, 详见 {@link ReconfigurationSchemeDTO}。
+ * 主表 fhzg_recon_result 由单条变为多条(每方案一条)。
+ * 顶层 objective(共享排序配置) 不入库, 由 @JsonIgnoreProperties 忽略。
  */
 @Data
 @NoArgsConstructor
@@ -36,25 +45,26 @@ public class RawResultDTO {
     @JsonProperty("detalDesc")
     private String detalDesc;
 
-    /** 开关操作(简化版), 源 JSON 为 PascalCase "SwitchOp" */
-    @JsonProperty("SwitchOp")
-    private SwitchOpDTO switchOp;
-
-    @JsonProperty("switchSeq")
-    private SwitchSeqDTO switchSeq;
-
-    @JsonProperty("feederResult")
-    private FeederResultDTO feederResult;
-
-    @JsonProperty("volResult")
-    private VolResultDTO volResult;
-
-    @JsonProperty("switchResult")
-    private SwitchResultDTO switchResult;
-
-    @JsonProperty("finalCheck")
-    private FinalCheckDTO finalCheck;
-
-    @JsonProperty("metrics")
-    private MetricsDTO metrics;
-}
+    /** [FHZG-RECON-MULTI] 多方案容器 */
+    @JsonProperty("reconfiguration_schemes")
+    private ReconfigurationSchemesDTO reconfigurationSchemes;
+
+    /**
+     * reconfiguration_schemes 容器.
+     * count / sort_by / order / lower_is_better / errors 均不入库; 仅取 list。
+     * errors 非空时不影响入库(忽略); 缺子节点的方案跳过对应子表。
+     */
+    @Data
+    @NoArgsConstructor
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class ReconfigurationSchemesDTO {
+
+        private Integer count;
+
+        /** 算法侧错误信息, 仅忽略, 不入库不阻断。 */
+        private JsonNode errors;
+
+        @JsonProperty("list")
+        private List<ReconfigurationSchemeDTO> list;
+    }
+}

+ 54 - 0
api/load-transfer-si-api/src/main/java/com/hdkj/lt/modle/dto/recon/ReconfigurationSchemeDTO.java

@@ -0,0 +1,54 @@
+package com.hdkj.lt.modle.dto.recon;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.JsonNode;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 单个重构方案 (reconfiguration_schemes.list[] 一项).
+ * <p>
+ * [FHZG-RECON-MULTI] 新结构: 原 raw_result 顶层的 SwitchOp / switchSeq / feederResult /
+ * volResult / switchResult / finalCheck / metrics 全部下移到每个 scheme 内;
+ * 另含方案标识 rank / scheme_id / scheme_name 与 objective.
+ * metric_new 不入库, 由 @JsonIgnoreProperties 忽略.
+ */
+@Data
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ReconfigurationSchemeDTO {
+
+    private Integer rank;
+
+    @JsonProperty("scheme_id")
+    private String schemeId;
+
+    @JsonProperty("scheme_name")
+    private String schemeName;
+
+    /** 方案 objective (含 value / improvement_vs_initial); 入主表 objective JSON 列。顶层共享 objective 不入库。 */
+    private JsonNode objective;
+
+    /** 开关操作(简化版), 源 JSON 为 PascalCase "SwitchOp" */
+    @JsonProperty("SwitchOp")
+    private SwitchOpDTO switchOp;
+
+    @JsonProperty("switchSeq")
+    private SwitchSeqDTO switchSeq;
+
+    @JsonProperty("feederResult")
+    private FeederResultDTO feederResult;
+
+    @JsonProperty("volResult")
+    private VolResultDTO volResult;
+
+    @JsonProperty("switchResult")
+    private SwitchResultDTO switchResult;
+
+    @JsonProperty("finalCheck")
+    private FinalCheckDTO finalCheck;
+
+    @JsonProperty("metrics")
+    private MetricsDTO metrics;
+}

+ 13 - 0
api/load-transfer-si-api/src/main/java/com/hdkj/lt/modle/po/FhzgReconResult.java

@@ -1,6 +1,7 @@
 package com.hdkj.lt.modle.po;
 
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
@@ -50,6 +51,18 @@ public class FhzgReconResult {
     /** 详细描述(detalDesc) */
     private String detalDesc;
 
+    // ===== [FHZG-RECON-MULTI] 多方案字段 (raw_result.reconfiguration_schemes.list[] 每项) =====
+    /** 方案序号(rank); rank 为 MySQL 保留字, 需反引号 */
+    @TableField("`rank`")
+    private Integer rank;
+
+    /** 方案ID(scheme_id) */
+    private String schemeId;
+
+    /** 方案 objective(JSON 串, 存 JSON 列; 含 value/improvement_vs_initial。顶层共享 objective 不入库) */
+    private String objective;
+    // ===== [FHZG-RECON-MULTI] END =====
+
     /** 安全校核是否安全(finalCheck.is_safe) */
     private Boolean finalCheckIsSafe;
 

+ 106 - 88
services/load-transfer-si/src/main/java/com/hdkj/lt/si/service/recon/impl/ReconResultServiceImpl.java

@@ -2,6 +2,7 @@ package com.hdkj.lt.si.service.recon.impl;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -128,105 +129,108 @@ public class ReconResultServiceImpl implements ReconResultService {
         }
 
         Map<String, Integer> counts = new LinkedHashMap<>();
+        //获取方案列表
+        List<ReconfigurationSchemeDTO> schemes = extractSchemes(dto);
+        for (ReconfigurationSchemeDTO scheme : schemes) {
+            // 1. 主表
+            FhzgReconResult main = buildMain(dto,scheme);
+            main.setEventId(eventId);
+            main.setRawResult(rawResultJson);
+            resultMapper.insert(main);
+            Long resultId = main.getId();
+            counts.merge("result", 1, Integer::sum);
+
+            // 2. 开关操作(简化版)
+            if (scheme.getSwitchOp() != null) {
+                counts.merge("switch_op", insertSwitchOp(scheme.getSwitchOp(), resultId), Integer::sum);
+            }
 
-        // 2. 主表
-        FhzgReconResult main = buildMain(dto);
-        main.setEventId(eventId);
-        main.setRawResult(rawResultJson);
-        resultMapper.insert(main);
-        Long resultId = main.getId();
-        counts.put("result", 1);
-
-        // 3. 开关操作(简化版)
-        if (dto.getSwitchOp() != null) {
-            int n = insertSwitchOp(dto.getSwitchOp(), resultId);
-            counts.put("switch_op", n);
-        }
-
-        // 4. 开关操作序列(详细)
-        if (dto.getSwitchSeq() != null) {
-            int n = insertSwitchSeq(dto.getSwitchSeq(), resultId);
-            counts.put("switch_seq", n);
-        }
-
-        // 5. 馈线结果
-        if (dto.getFeederResult() != null) {
-            int n = insertFeederResult(dto.getFeederResult(), resultId);
-            counts.put("feeder_result", n);
-        }
+            // 3. 开关操作序列(详细)
+            if (scheme.getSwitchSeq() != null) {
+                counts.merge("switch_seq", insertSwitchSeq(scheme.getSwitchSeq(), resultId), Integer::sum);
+            }
 
-        // 6. 电压结果(汇总+详情)
-        if (dto.getVolResult() != null) {
-            if (dto.getVolResult().getSummary() != null) {
-                volResultMapper.insert(buildVolResult(dto.getVolResult().getSummary(), resultId));
-                counts.put("vol_result", 1);
+            // 4. 馈线结果
+            if (scheme.getFeederResult() != null) {
+                counts.merge("feeder_result", insertFeederResult(scheme.getFeederResult(), resultId), Integer::sum);
             }
-            if (dto.getVolResult().getDetails() != null) {
-                int n = insertVolDetail(dto.getVolResult().getDetails(), resultId);
-                counts.put("vol_detail", n);
+
+            // 5. 电压结果(汇总+详情)
+            if (scheme.getVolResult() != null) {
+                if (scheme.getVolResult().getSummary() != null) {
+                    volResultMapper.insert(buildVolResult(scheme.getVolResult().getSummary(), resultId));
+                    counts.merge("vol_result", 1, Integer::sum);
+                }
+                if (scheme.getVolResult().getDetails() != null) {
+                    counts.merge("vol_detail", insertVolDetail(scheme.getVolResult().getDetails(), resultId), Integer::sum);
+                }
             }
-        }
 
-        // 7. 开关状态详情(summary 折叠进主表)
-        if (dto.getSwitchResult() != null && dto.getSwitchResult().getDetails() != null) {
-            int n = insertSwitchResultDetail(dto.getSwitchResult().getDetails(), resultId);
-            counts.put("switch_result_detail", n);
-        }
+            // 6. 开关状态详情(summary 折叠进主表)
+            if (scheme.getSwitchResult() != null && scheme.getSwitchResult().getDetails() != null) {
+                counts.merge("switch_result_detail", insertSwitchResultDetail(scheme.getSwitchResult().getDetails(), resultId), Integer::sum);
+            }
 
-        // 8. 运行指标
-        if (dto.getMetrics() != null) {
-            metricsMapper.insert(buildMetrics(dto.getMetrics(), resultId));
-            counts.put("metrics", 1);
+            // 7. 运行指标
+            if (scheme.getMetrics() != null) {
+                metricsMapper.insert(buildMetrics(scheme.getMetrics(), resultId));
+                counts.merge("metrics", 1, Integer::sum);
+            }
         }
 
         log.info("重构方案counts:{}", JSON.toJSONString(counts));
         ReconSaveResultVO vo = new ReconSaveResultVO();
         vo.setSuccess(true);
-        vo.setMainId(resultId);
-        vo.setEventId(main.getEventId());
+//        vo.setMainId(resultId);
+        vo.setEventId(eventId);
         vo.setCounts(counts);
         return vo;
     }
 
+    /**
+     * 构建请求参数
+     */
     private Map<String, Object> buildReconRequestParams(Map<String, Object> params){
         Map<String, Object> root = new HashMap<>();
-        if(Objects.nonNull(params)){
+        if(Objects.nonNull(params)) {
             String feederId = MapUtils.getString(params, "feeder_id");
             String pointTime = MapUtils.getString(params, "point_time");
             List<Jxz> jxzList = getFeederGroup(feederId);
             List<String> feederIds = jxzList.stream().map(Jxz::getFeederId).distinct().collect(Collectors.toList());
-            Jxz jxz = jxzList.get(0);
-            // county
-            Map<String, Object> county = new HashMap<>();
-            county.put("county_id", jxz.getMaintOrg());
-            county.put("county_sid", jxz.getMaintOrgName());
-            county.put("county_name", jxz.getMaintOrgName());
-            root.put("county", county);
-
-            // snapshot
-            Map<String, Object> snapshot = new HashMap<>();
-            snapshot.put("snapshot_id", pointTime);
-            snapshot.put("alarm_state_estimation_time", pointTime);
-            snapshot.put("point_time", pointTime);
-            root.put("snapshot", snapshot);
-
-            // problem
-            Map<String, Object> problem = new HashMap<>();
-            problem.put("problem_feeder_ids", Collections.singletonList(feederId));
-            problem.put("trigger_type", "load_rate");
-            problem.put("trigger_reason", "feeder_load_rate_over_limit");
-            problem.put("trigger_source", "customer_backend_alarm");
-            root.put("problem", problem);
-
-            // feeder_group
-            Map<String, Object> feederGroup = new HashMap<>();
-            feederGroup.put("group_id", jxz.getJxzId());
-            feederGroup.put("group_sid", jxz.getJxzId());
-            feederGroup.put("group_name", jxz.getJxzName());
-            feederGroup.put("feeder_ids", feederIds);
-            root.put("feeder_group", feederGroup);
-            // algorithm_config【外部可传入覆盖】
-            root.put("algorithm_config", algorithmProp.toAlgorithmConfigMap());
+            if (!CollectionUtils.isEmpty(jxzList)) {
+                Jxz jxz = jxzList.get(0);
+                // county
+                Map<String, Object> county = new HashMap<>();
+                county.put("county_id", jxz.getMaintOrg());
+                county.put("county_sid", jxz.getMaintOrgName());
+                county.put("county_name", jxz.getMaintOrgName());
+                root.put("county", county);
+
+                // snapshot
+                Map<String, Object> snapshot = new HashMap<>();
+                snapshot.put("snapshot_id", pointTime);
+                snapshot.put("alarm_state_estimation_time", pointTime);
+                snapshot.put("point_time", pointTime);
+                root.put("snapshot", snapshot);
+
+                // problem
+                Map<String, Object> problem = new HashMap<>();
+                problem.put("problem_feeder_ids", Collections.singletonList(feederId));
+                problem.put("trigger_type", "load_rate");
+                problem.put("trigger_reason", "feeder_load_rate_over_limit");
+                problem.put("trigger_source", "customer_backend_alarm");
+                root.put("problem", problem);
+
+                // feeder_group
+                Map<String, Object> feederGroup = new HashMap<>();
+                feederGroup.put("group_id", jxz.getJxzId());
+                feederGroup.put("group_sid", jxz.getJxzId());
+                feederGroup.put("group_name", jxz.getJxzName());
+                feederGroup.put("feeder_ids", feederIds);
+                root.put("feeder_group", feederGroup);
+                // algorithm_config【外部可传入覆盖】
+                root.put("algorithm_config", algorithmProp.toAlgorithmConfigMap());
+            }
         }
         return root;
     }
@@ -235,11 +239,19 @@ public class ReconResultServiceImpl implements ReconResultService {
     }
     // ==================== 构建主表 ====================
 
-    private FhzgReconResult buildMain(RawResultDTO dto) {
+    /** [FHZG-RECON-MULTI] 取方案列表; 容器或 list 为空时返回空表(不报错, 入 0 条)。 */
+    private List<ReconfigurationSchemeDTO> extractSchemes(RawResultDTO dto) {
+        if (dto.getReconfigurationSchemes() == null || dto.getReconfigurationSchemes().getList() == null) {
+            return Collections.emptyList();
+        }
+        return dto.getReconfigurationSchemes().getList();
+    }
+
+    private FhzgReconResult buildMain(RawResultDTO dto, ReconfigurationSchemeDTO scheme) {
         FhzgReconResult m = new FhzgReconResult();
+        // 共享标量(每个方案主记录重复)
+        m.setId(IdWorker.getId());
         m.setGroupId(dto.getGroupId());
-        //目前就一个方案
-        m.setSchemeName("方案一");
         m.setGroupSid(dto.getGroupSid());
         m.setGroupName(dto.getGroupName());
         m.setStAreaId(dto.getStAreaId());
@@ -248,14 +260,20 @@ public class ReconResultServiceImpl implements ReconResultService {
         m.setComputeResult(dto.getComputeResult());
         m.setDetalDesc(dto.getDetalDesc());
 
-        // finalCheck 折叠
-        if (dto.getFinalCheck() != null) {
-            m.setFinalCheckIsSafe(dto.getFinalCheck().getSafe());
-            m.setFinalCheckDetails(dto.getFinalCheck().getDetails());
+        // [FHZG-RECON-MULTI] 方案标识 + objective
+        m.setRank(scheme.getRank());
+        m.setSchemeId(scheme.getSchemeId());
+        m.setSchemeName(scheme.getSchemeName());
+        m.setObjective(toJson(scheme.getObjective()));
+
+        // finalCheck 折叠(per-scheme)
+        if (scheme.getFinalCheck() != null) {
+            m.setFinalCheckIsSafe(scheme.getFinalCheck().getSafe());
+            m.setFinalCheckDetails(scheme.getFinalCheck().getDetails());
         }
-        // switchResult.summary 折叠
-        if (dto.getSwitchResult() != null) {
-            m.setSwitchResultSummary(dto.getSwitchResult().getSummary());
+        // switchResult.summary 折叠(per-scheme)
+        if (scheme.getSwitchResult() != null) {
+            m.setSwitchResultSummary(scheme.getSwitchResult().getSummary());
         }
         m.setSnapshotTime(LocalDateTime.now());
         return m;