From fdf140677f1ebf6a9964d158464eec09414b3d91 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期二, 08 九月 2026 15:01:01 +0800
Subject: [PATCH] 支持跨测试逐电池拼接统计

---
 battery-business/src/main/java/com/battery/business/report/SpliceReportService.java |   25 ++++++++-----------------
 1 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/battery-business/src/main/java/com/battery/business/report/SpliceReportService.java b/battery-business/src/main/java/com/battery/business/report/SpliceReportService.java
index fca9c40..5860a9a 100644
--- a/battery-business/src/main/java/com/battery/business/report/SpliceReportService.java
+++ b/battery-business/src/main/java/com/battery/business/report/SpliceReportService.java
@@ -37,51 +37,42 @@
   return result.stream().sorted(Comparator.comparingLong(Candidate::startedAt)
       .thenComparingLong(value -> value.selection().testId())).toList();
  }
- /** 校验至少两个同组测试选择相同的参与电池集合,按提交顺序接续真实循环。 */
+ /** 校验每个测试电池来源并按提交顺序逐段接续真实循环。 */
  public Matrix preview(List<SpliceReportRequest.Selection> selections) {
   if (selections == null || selections.size() < 2 || selections.contains(null)
       || new HashSet<>(selections).size() != selections.size())
    throw new ServiceException("请选择至少两个不重复的检测完成测试电池");
   Map<Long, TTest> loaded = new LinkedHashMap<>();
-  Map<Long, List<TTestBattery>> selected = new LinkedHashMap<>();
-  Long group = null;
+  Map<SpliceReportRequest.Selection, TTestBattery> selected = new LinkedHashMap<>();
   for (var selection : selections) {
    if (selection.testId() == null || selection.testBatteryId() == null) throw new ServiceException("测试和电池身份不能为空");
    TTest test = loaded.computeIfAbsent(selection.testId(), tests::selectTestById);
    if (test == null || !"COMPLETED".equals(test.getTestStatus())) throw new ServiceException("仅可选择检测完成测试");
    TTestBattery battery = test.getBatteries().stream().filter(row -> selection.testBatteryId().equals(row.getTestBatteryId()))
        .findFirst().orElseThrow(() -> new ServiceException("电池不属于所选测试"));
-   if (group == null) group = battery.getGroupId();
-   if (!Objects.equals(group, battery.getGroupId())) throw new ServiceException("拼接测试必须属于同一电池组");
-   selected.computeIfAbsent(selection.testId(), key -> new ArrayList<>()).add(battery);
-  }
-  if (selected.size() < 2) throw new ServiceException("请至少选择两个不同测试");
-  Set<String> common = null;
-  for (var batteries : selected.values()) {
-   Set<String> names = new HashSet<>(batteries.stream().map(TTestBattery::getBatteryNo).toList());
-   if (common == null) common = names;
-   if (names.size() != batteries.size() || !common.equals(names)) throw new ServiceException("拼接测试必须选择相同的共同参与电池集合");
+   selected.put(selection, battery);
   }
   List<Map<String, Object>> segments = new ArrayList<>();
   Set<Integer> mappedCycles = new TreeSet<>();
   Integer previousEnd = null;
   for (var entry : selected.entrySet()) {
-   List<Map<String, Object>> cycles = data.cycles(entry.getKey()), steps = data.steps(entry.getKey()), records = data.records(entry.getKey());
+   long testId = entry.getKey().testId();
+   List<Map<String, Object>> cycles = data.cycles(testId), steps = data.steps(testId), records = data.records(testId);
    List<Map<String, Object>> current = new ArrayList<>();
    Set<Integer> sourceCycles = new TreeSet<>();
-   for (TTestBattery battery : entry.getValue()) {
+   for (TTestBattery battery : List.of(entry.getValue())) {
     var rows = batteryRows(cycles, battery);
     var stepRows = batteryRows(steps, battery);
     var nos = java.util.stream.Stream.of(rows, stepRows, batteryRows(records, battery)).flatMap(List::stream)
         .map(this::cycle).filter(no -> no > 0).distinct().sorted().toList();
     Map<String, Object> segment = new LinkedHashMap<>();
-    segment.put("source", candidate(loaded.get(entry.getKey()), battery));
+    segment.put("source", candidate(loaded.get(testId), battery));
     segment.put("cycles", rows); segment.put("steps", stepRows);
     segment.put("businessFields", battery.getFields());
     segment.put("originalCycleNos", nos); segment.put("statistics", statistics(rows, stepRows, nos));
     current.add(segment); sourceCycles.addAll(nos);
    }
-   // 同一测试的全部电池共用偏移;首个非空段保留原号,后段首循环紧接前段末循环。
+   // 每个测试电池独立计算偏移;空段不占用循环,各指标共用同一定位。
    int offset = previousEnd == null || sourceCycles.isEmpty() ? 0 : previousEnd + 1 - sourceCycles.iterator().next();
    current.forEach(segment -> segment.put("offset", offset));
    for (int no : sourceCycles) mappedCycles.add(no + offset);

--
Gitblit v1.7.1