From 04a0f85f968b874b1b43cf88f91993024a09d880 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期二, 08 九月 2026 17:59:18 +0800
Subject: [PATCH] 独立校验拼接来源详情并保留旧版人工内容
---
battery-business/src/main/java/com/battery/business/report/SpliceReportService.java | 35 +++++++++++++++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 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 3a4dc4d..c1280a3 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
@@ -119,8 +119,10 @@
@Transactional
public Map<String,Object> create(SpliceReportRequest request, long uid, String user) {
var settings = settings(request.settings(), true);
+ settings.putIfAbsent("sourceDetailOverrides", Map.of());
Matrix matrix = freeze(preview(request.selections()), fields(settings));
validateStatistics(settings, matrix.segments());
+ validateSourceDetails(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());
@@ -146,6 +148,7 @@
var snapshot = current(id, request.baseVersionNo());
var settings = settings(request.settings(), false);
validateStatistics(settings, segments(snapshot));
+ validateSourceDetails(settings, segments(snapshot));
snapshot.put("name", request.name().trim()); snapshot.put("description", request.description()); snapshot.put("settings", settings);
reports.append(id, request.baseVersionNo() + 1, request.name().trim(), snapshot.toJSONString(), uid, user, request.changeSummary().trim());
return get(id, null);
@@ -158,7 +161,16 @@
var snapshot = current(id, base);
var selections = JSON.parseArray(snapshot.getString("selections"), SpliceReportRequest.Selection.class);
var settings = settings(snapshot.getJSONObject("settings"), false);
+ // 主动更新才启用独立来源详情;旧版本读取和普通编辑不隐式迁移。
+ if (!settings.containsKey("sourceDetailOverrides")) {
+ // 旧版实验已按来源保存,可直接保留;旧字段人工值仍留在原报表字段,不按名称改绑共享身份。
+ Map<String,Object> details = new LinkedHashMap<>();
+ var experiments = JSON.parseObject(JSON.toJSONString(settings.getOrDefault("sourceExperimentNames", Map.of())));
+ experiments.forEach((key, value) -> details.put(key, Map.of("experimentName", value)));
+ settings.put("sourceDetailOverrides", details);
+ }
Matrix matrix = freeze(preview(selections), fields(settings));
+ validateSourceDetails(settings, matrix.segments());
// 人工值绑定原循环身份,刷新只清理已不存在的循环,不按新的拼接循环号迁移。
var overrides = JSON.parseObject(JSON.toJSONString(settings.getOrDefault("statisticValues", Map.of())));
overrides.keySet().retainAll(statisticKeys(matrix.segments()));
@@ -229,6 +241,29 @@
return allowed;
}
+ private void validateSourceDetails(Map<String,Object> settings, List<Map<String,Object>> segments) {
+ Object submitted = settings.get("sourceDetailOverrides");
+ if (submitted == null) return;
+ if (!(submitted instanceof Map<?,?> overrides)) throw new ServiceException("详情调整格式无效");
+ Set<String> sources = new HashSet<>();
+ for (var segment : segments) {
+ var source = JSON.parseObject(JSON.toJSONString(segment.get("source")), Candidate.class);
+ sources.add(source.selection().testId() + "|" + source.selection().testBatteryId());
+ }
+ // 详情按测试电池归属;名称与分类不解释为共享字段身份、单位或设备事实。
+ if (!sources.containsAll(overrides.keySet())) throw new ServiceException("详情调整不属于所选测试电池");
+ for (Object value : overrides.values()) {
+ if (!(value instanceof Map<?,?> override) || !Set.of("experimentName", "fieldValues").containsAll(override.keySet())) throw new ServiceException("详情调整无效");
+ if (override.containsKey("experimentName") && (!(override.get("experimentName") instanceof String name) || name.length() > 500)) throw new ServiceException("实验名称无效");
+ if (!override.containsKey("fieldValues")) continue;
+ if (!(override.get("fieldValues") instanceof Map<?,?> values)) throw new ServiceException("详情字段格式无效");
+ for (var entry : values.entrySet()) {
+ if (!(entry.getKey() instanceof String key) || !key.matches("(?:battery|special)\\|.{1,100}")
+ || !(entry.getValue() instanceof String text) || text.length() > 500) throw new ServiceException("详情字段名称或值无效");
+ }
+ }
+ }
+
private void validateStatistics(Map<String,Object> settings, List<Map<String,Object>> segments) {
Object submitted = settings.get("statisticValues");
if (submitted == null) return;
--
Gitblit v1.7.1