From eee00fd63f558cfa0caf737c868de8fc0c652fcd Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期一, 07 九月 2026 10:39:30 +0800
Subject: [PATCH] 修复对比字段模板结构与权限边界

---
 battery-business/src/main/java/com/battery/business/report/CompareReportService.java |   35 +++++++++++++++++++++++++++++++----
 1 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/battery-business/src/main/java/com/battery/business/report/CompareReportService.java b/battery-business/src/main/java/com/battery/business/report/CompareReportService.java
index 13140ec..c9ee39f 100644
--- a/battery-business/src/main/java/com/battery/business/report/CompareReportService.java
+++ b/battery-business/src/main/java/com/battery/business/report/CompareReportService.java
@@ -93,10 +93,10 @@
             throw new ServiceException("请至少添加两条比对项");
         validateSettings(request.settings());
         List<Item> items = preview(request.selections()).stream().map(item -> new Item(item.source(), item.zeroTime(), item.records(), item.logicalMapping(),
-                item.businessFields().stream().filter(field -> request.settings().batteryTemplateFields().contains(field.getFieldName())).toList())).toList();
+                item.businessFields().stream().filter(field -> selectedBusinessField(field, request.settings())).toList())).toList();
         Map<String, Object> snapshot = new LinkedHashMap<>();
         snapshot.put("name", request.name().trim()); snapshot.put("description", request.description());
-        snapshot.put("experimentName", request.experimentName()); snapshot.put("items", items); snapshot.put("settings", request.settings());
+        snapshot.put("experimentName", request.experimentName()); snapshot.put("items", items); snapshot.put("settings", snapshotSettings(request.settings()));
         snapshot.put("units", Map.of("voltage", "V", "current", "A", "temperature", "℃", "positiveVoltage", "V", "negativeVoltage", "V", "capacity", "Ah", "energy", "Wh"));
         snapshot.put("displayUnits", Map.of("voltage", "V", "current", "mA", "temperature", "℃", "positiveVoltage", "V", "negativeVoltage", "V", "capacity", "mAh", "energy", "mWh"));
         snapshot.put("timeUnit", "epoch-milliseconds");
@@ -127,7 +127,7 @@
         var snapshot = currentSnapshot(id, request.baseVersionNo());
         validateSettings(request.settings());
         snapshot.put("name", request.name().trim()); snapshot.put("description", request.description());
-        snapshot.put("experimentName", request.experimentName()); snapshot.put("settings", request.settings());
+        snapshot.put("experimentName", request.experimentName()); snapshot.put("settings", snapshotSettings(request.settings()));
         reports.append(id, request.baseVersionNo() + 1, request.name().trim(), JSON.toJSONString(snapshot, JSONWriter.Feature.WriteMapNullValue),
                 operatorId, operatorName, request.changeSummary().trim());
         return get(id);
@@ -142,7 +142,7 @@
         var settings = JSON.parseObject(JSON.toJSONString(snapshot.get("settings")), CompareReportRequest.Settings.class);
         var updated = preview(items.stream().map(item -> item.source().selection()).toList()).stream()
                 .map(item -> new Item(item.source(), item.zeroTime(), item.records(), item.logicalMapping(),
-                        item.businessFields().stream().filter(field -> settings.batteryTemplateFields().contains(field.getFieldName())).toList())).toList();
+                        item.businessFields().stream().filter(field -> selectedBusinessField(field, settings)).toList())).toList();
         snapshot.put("items", updated);
         reports.append(id, request.baseVersionNo() + 1, snapshot.getString("name"), JSON.toJSONString(snapshot, JSONWriter.Feature.WriteMapNullValue),
                 operatorId, operatorName, "按最新来源生成:" + request.changeSummary().trim());
@@ -176,6 +176,33 @@
         List<String> fields = new ArrayList<>(settings.batteryTemplateFields()); fields.addAll(settings.specialFields());
         if (fields.stream().anyMatch(field -> field == null || field.isBlank() || field.length() > 100)
                 || new HashSet<>(fields).size() != fields.size()) throw new ServiceException("报表字段无效或重复");
+        if (settings.fieldStructure() != null)
+        {
+            var structure = settings.fieldStructure();
+            if (structure.stream().anyMatch(Objects::isNull) || structure.size() != fields.size()
+                    || !new HashSet<>(structure.stream().map(CompareField::name).toList()).equals(new HashSet<>(fields))
+                    || structure.stream().anyMatch(field -> "battery".equals(field.category()) != settings.batteryTemplateFields().contains(field.name())))
+                throw new ServiceException("报表字段结构与所选字段不一致");
+        }
+    }
+
+    private boolean selectedBusinessField(CurrentBatteryField value, CompareReportRequest.Settings settings)
+    {
+        // 新结构按共享定义身份归属,字段改名不借用另一个同名字段的值;旧版本继续按其冻结名称读取。
+        if (settings.fieldStructure() == null) return settings.batteryTemplateFields().contains(value.getFieldName());
+        return settings.fieldStructure().stream().anyMatch(field -> "battery".equals(field.category())
+                && (field.fieldDefinitionId() == null ? field.name().equals(value.getFieldName()) : field.fieldDefinitionId().equals(value.getFieldDefinitionId())));
+    }
+
+    private Map<String, Object> snapshotSettings(CompareReportRequest.Settings settings)
+    {
+        var result = new LinkedHashMap<String, Object>();
+        result.put("metrics", settings.metrics()); result.put("seriesColors", settings.seriesColors());
+        result.put("batteryTemplateFields", settings.batteryTemplateFields()); result.put("specialFields", settings.specialFields());
+        result.put("detailFieldValues", settings.detailFieldValues());
+        // 独立复制结构而非保存模板引用,重开、编辑与打印均不重新读取模板或共享定义。
+        if (settings.fieldStructure() != null) result.put("fieldStructure", settings.fieldStructure());
+        return result;
     }
 
     private List<Candidate> candidates(TTest test, List<Map<String, Object>> records)

--
Gitblit v1.7.1