yeg
2026-09-08 5da31bf1b32fca7f80ec6e73569c98af55e823d1
完成 Ticket07 拼接逐电池闭环
2个文件已修改
36 ■■■■■ 已修改文件
battery-business/src/main/java/com/battery/business/report/SpliceFieldTemplateService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
battery-business/src/main/java/com/battery/business/report/SpliceReportService.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
battery-business/src/main/java/com/battery/business/report/SpliceFieldTemplateService.java
@@ -42,9 +42,9 @@
        return fields.stream().map(field -> {
            if (!names.add(field.name())) throw new ServiceException("拼接字段不能重复");
            Long id = field.fieldDefinitionId();
            if ("battery".equals(field.category()) && resolveDefinitions)
                id = current.stream().filter(item -> field.fieldDefinitionId() == null
                        ? item.getFieldName().equals(field.name()) : item.getFieldId().equals(field.fieldDefinitionId()))
            // 控制台字段只有名称;没有明确共享身份时不得凭同名绑定组字段。
            if ("battery".equals(field.category()) && resolveDefinitions && id != null)
                id = current.stream().filter(item -> item.getFieldId().equals(field.fieldDefinitionId()))
                    .findFirst().orElseThrow(() -> new ServiceException("共享字段不存在:" + field.name())).getFieldId();
            if (id != null && !ids.add(id)) throw new ServiceException("共享字段不能重复");
            return new SpliceField(field.name(), field.category(), field.unit(), id, field.displayName());
battery-business/src/main/java/com/battery/business/report/SpliceReportService.java
@@ -58,9 +58,7 @@
  for (var entry : selected.entrySet()) {
   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 : List.of(entry.getValue())) {
   TTestBattery battery = 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)
@@ -69,15 +67,25 @@
    segment.put("source", candidate(loaded.get(testId), battery));
    segment.put("cycles", rows); segment.put("steps", stepRows);
    segment.put("businessFields", battery.getFields());
    var detail = loaded.get(testId).getConsoleDetail();
    if (detail != null) {
     // 只冻结所选测试电池的填写值,字段名称不推断共享字段身份或单位。
     Map<String,Object> frozen = new LinkedHashMap<>();
     frozen.put("experimentName", detail.getExperimentName());
     frozen.put("batteryFields", detail.getBatteryFields()); frozen.put("specialFields", detail.getSpecialFields());
     Map<String,String> values = new LinkedHashMap<>();
     detail.getFieldValues().forEach((name, byBattery) -> {
      if (byBattery.containsKey(battery.getBatteryNo())) values.put(name, byBattery.get(battery.getBatteryNo()));
     });
     frozen.put("fieldValues", values); segment.put("consoleDetail", frozen);
    }
    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);
   if (!sourceCycles.isEmpty()) previousEnd = Collections.max(sourceCycles) + offset;
   segments.addAll(current);
   int offset = previousEnd == null || nos.isEmpty() ? 0 : previousEnd + 1 - nos.get(0);
   segment.put("offset", offset);
   for (int no : nos) mappedCycles.add(no + offset);
   if (!nos.isEmpty()) previousEnd = nos.get(nos.size() - 1) + offset;
   segments.add(segment);
  }
  return new Matrix(segments, new ArrayList<>(mappedCycles));
 }
@@ -114,6 +122,7 @@
  Matrix matrix = freeze(preview(request.selections()), fields(settings));
  validateStatistics(settings, matrix.segments());
  Map<String,Object> snapshot = new LinkedHashMap<>();
  snapshot.put("spliceMode", "battery-segments");
  snapshot.put("name", request.name().trim()); snapshot.put("description", request.description());
  snapshot.put("selections", request.selections()); snapshot.put("segments", matrix.segments());
  snapshot.put("cycleNos", matrix.cycleNos()); snapshot.put("settings", settings);
@@ -155,6 +164,7 @@
  overrides.keySet().retainAll(statisticKeys(matrix.segments()));
  settings.put("statisticValues", overrides);
  snapshot.put("settings", settings); snapshot.put("segments", matrix.segments()); snapshot.put("cycleNos", matrix.cycleNos());
  snapshot.put("spliceMode", "battery-segments");
  reports.append(id, base + 1, snapshot.getString("name"), snapshot.toJSONString(), uid, user, "按最新来源生成:" + summary.trim());
  return get(id, null);
 }