yeg
2026-09-06 37600a85b79387ab6afa7bf342eedbf938331e1d
battery-business/src/main/java/com/battery/business/report/CompareReportService.java
@@ -22,7 +22,7 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/** 对比来源与首版快照共用同一范围解析,测量始终来自后端当前有效数据。 */
/** 首次保存和主动更新解析当前来源,普通编辑及历史查看只读取独立快照。 */
@Service
public class CompareReportService
{
@@ -106,14 +106,58 @@
    /** 重开只读取保存版本,来源测试、字段或映射已删除也不重新解析。 */
    public Map<String, Object> get(long id)
    { return get(id, null); }
    /** 指定版本按其冻结内容还原,操作信息来自正式版本记录。 */
    public Map<String, Object> get(long id, Integer versionNo)
    {
        var version = reports.get(id);
        var version = reports.get(id, versionNo);
        Map<String, Object> result = JSON.parseObject(version.snapshotJson());
        result.put("id", id); result.put("versionNo", version.versionNo());
        result.put("creator", version.report().creator()); result.put("createdAt", version.report().createdAt());
        result.put("operatorName", version.operatorName()); result.put("versionCreatedAt", version.versionCreatedAt());
        result.put("changeSummary", version.changeSummary());
        return result;
    }
    /** 普通编辑追加展示版本,测量、来源身份和单位完全沿用基准快照。 */
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> edit(long id, CompareReportEditRequest request, long operatorId, String operatorName)
    {
        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());
        reports.append(id, request.baseVersionNo() + 1, request.name().trim(), JSON.toJSONString(snapshot, JSONWriter.Feature.WriteMapNullValue),
                operatorId, operatorName, request.changeSummary().trim());
        return get(id);
    }
    /** 仅主动更新重读来源;人工表格值仍保留在设置中,不覆盖本次测量快照。 */
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> refresh(long id, CompareReportEditRequest.Refresh request, long operatorId, String operatorName)
    {
        var snapshot = currentSnapshot(id, request.baseVersionNo());
        var items = JSON.parseArray(JSON.toJSONString(snapshot.get("items")), Item.class);
        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();
        snapshot.put("items", updated);
        reports.append(id, request.baseVersionNo() + 1, snapshot.getString("name"), JSON.toJSONString(snapshot, JSONWriter.Feature.WriteMapNullValue),
                operatorId, operatorName, "按最新来源生成:" + request.changeSummary().trim());
        return get(id);
    }
    private com.alibaba.fastjson2.JSONObject currentSnapshot(long id, int baseVersionNo)
    {
        // 同一报表内串行追加;陈旧页面需重新打开,不从历史版生成回滚版本。
        reports.lock(id);
        var current = reports.get(id);
        if (current.versionNo() != baseVersionNo) throw new ServiceException("报表已有新版本,请重新打开后编辑");
        return JSON.parseObject(current.snapshotJson());
    }
    private void validateSettings(CompareReportRequest.Settings settings)
    {
        Set<String> metrics = Set.of("voltage", "current", "temperature", "positiveVoltage", "negativeVoltage");