From 497e08d7d183e511dfc752486353ba957f3e9a2c Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期二, 08 九月 2026 17:13:43 +0800
Subject: [PATCH] 集成化成工步版本与打印修复

---
 battery-business/src/main/java/com/battery/business/report/FormationReportService.java |   23 ++++++++++++-----------
 1 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/battery-business/src/main/java/com/battery/business/report/FormationReportService.java b/battery-business/src/main/java/com/battery/business/report/FormationReportService.java
index 5a02690..fa10e59 100644
--- a/battery-business/src/main/java/com/battery/business/report/FormationReportService.java
+++ b/battery-business/src/main/java/com/battery/business/report/FormationReportService.java
@@ -115,6 +115,7 @@
         settings = stepSettings(settings, matrix.items(), false);
         validateValues(settings, matrix.items()); validateChargeSelections(settings, matrix.items());
         var snapshot = new LinkedHashMap<String, Object>();
+        snapshot.put("curveMode", "actual-steps");
         snapshot.put("name", request.name().trim()); snapshot.put("description", request.description());
         snapshot.put("items", matrix.items()); snapshot.put("cycleNos", matrix.cycleNos()); snapshot.put("settings", settings);
         snapshot.put("units", Map.of("chargeCapacity", "Ah", "dischargeCapacity", "Ah", "chargeEnergy", "Wh", "dischargeEnergy", "Wh", "efficiency", "%", "energyEfficiency", "%"));
@@ -161,8 +162,12 @@
         Set<String> allowed = valueKeys(settings.fields(), matrix.items());
         Map<String, String> values = new LinkedHashMap<>();
         settings.values().forEach((key, value) -> { if (allowed.contains(key)) values.put(key, value); });
-        snapshot.put("items", matrix.items()); snapshot.put("cycleNos", matrix.cycleNos()); snapshot.put("settings", new Settings(validateFields(settings.fields(), false), values,
-                settings.chargeStepSelections() == null ? Map.of() : settings.chargeStepSelections(), settings.metrics(), settings.seriesColors(), settings.manualChargeSteps(), settings.curveStepSelections(), settings.hiddenSeriesKeys(), settings.activeCycle(), settings.sourceDetailOverrides()));
+        var refreshedSettings = new Settings(validateFields(settings.fields(), false), values,
+                settings.chargeStepSelections() == null ? Map.of() : settings.chargeStepSelections(), settings.metrics(), settings.seriesColors(),
+                settings.manualChargeSteps(), settings.curveStepSelections(), settings.hiddenSeriesKeys(), settings.activeCycle(), settings.sourceDetailOverrides());
+        snapshot.put("curveMode", "actual-steps");
+        snapshot.put("items", matrix.items()); snapshot.put("cycleNos", matrix.cycleNos());
+        snapshot.put("settings", stepSettings(refreshedSettings, matrix.items(), true));
         curveUnits(snapshot);
         reports.append(id, request.baseVersionNo() + 1, snapshot.getString("name"), json(snapshot), userId, userName, "按最新来源生成:" + request.changeSummary().trim());
         return get(id, null);
@@ -317,7 +322,8 @@
             if (refresh) choice = new FormationReportRequest.StepSelection(choice.charge().stream().filter(chargeAllowed::contains).toList(), choice.discharge().stream().filter(dischargeAllowed::contains).toList());
             if (choice.charge() == null || choice.discharge() == null || !chargeAllowed.containsAll(choice.charge()) || !dischargeAllowed.containsAll(choice.discharge())
                     || new HashSet<>(choice.charge()).size() != choice.charge().size() || new HashSet<>(choice.discharge()).size() != choice.discharge().size()) throw new ServiceException("曲线工步不属于当前测试电池、循环或充放电分组");
-            if (choice.charge().stream().anyMatch(choice.discharge()::contains)) throw new ServiceException("同一实际工步不能同时指定为充电和放电");
+            if (choice.charge().stream().anyMatch(choice.discharge()::contains) || requested.stream().anyMatch(choice.discharge()::contains))
+                throw new ServiceException("同一实际工步不能同时指定为充电和放电");
             selected.put(key, choice);
         }
         if (!refresh && ((settings.manualChargeSteps() != null && !allowed.containsAll(settings.manualChargeSteps().keySet()))
@@ -343,13 +349,9 @@
             // 早期版本未冻结工步时保持缺失,普通编辑不能重新读取设备事实。
             List<ChargeStep> choices = item.chargeSteps() == null ? List.of() : item.chargeSteps().getOrDefault(cycle, List.of());
             Integer selected = selections.get(key);
-            if (choices.stream().filter(step -> isReliableCharge(step.stepType())).count() == 1) {
-                int expected = choices.stream().filter(step -> isReliableCharge(step.stepType())).findFirst().get().stepNo();
-                if (selected != null && selected != expected) throw new ServiceException("充电工步选择与实际工步不一致");
-            } else if (!choices.isEmpty()) {
-                if (selected == null) throw new ServiceException("请为无法自动识别的充电工步完成选择");
-                if (choices.stream().noneMatch(step -> step.stepNo() == selected)) throw new ServiceException("所选充电工步不属于当前测试、电池和循环");
-            }
+            // 旧版保留冻结的单选事实,不用新增协议识别规则改判历史选择。
+            if (selected != null && choices.stream().noneMatch(step -> step.stepNo() == selected))
+                throw new ServiceException("所选充电工步不属于当前测试、电池和循环");
         }
     }
 
@@ -371,7 +373,6 @@
         }
         return result;
     }
-    private boolean isReliableCharge(String type) { return directions.resolve(type) == Direction.CHARGE; }
     private int number(Object value) { return value instanceof Number n ? n.intValue() : 0; }
     private BigDecimal decimal(Object value) { return value instanceof Number n ? new BigDecimal(n.toString()) : null; }
 

--
Gitblit v1.7.1