yeg
6 天以前 a04222c873e5e55f48c8d33b5c0bc46fa524ac8d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package com.battery.business.service.impl;
 
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
import com.battery.business.mapper.TTestMapper;
import com.battery.business.service.ITTestService;
import com.battery.business.service.ITestDataQueryService;
 
/** 三类数据直接读取尚存的持久化记录;修订在同一事实表内生效。 */
@Service
public class TestDataQueryServiceImpl implements ITestDataQueryService
{
    private final TTestMapper mapper;
    private final ITTestService tests;
 
    public TestDataQueryServiceImpl(TTestMapper mapper, ITTestService tests)
    { this.mapper = mapper; this.tests = tests; }
 
    /** 查询尚存实时采样与授权历史导入记录,保留检测柜和采集器各自的设备时间。 */
    @Override public List<Map<String, Object>> records(Long testId)
    {
        tests.selectTestById(testId);
        List<Map<String, Object>> rows = normalizeApiTimes(mapper.selectPersistedFinalRealtimeRecords(testId));
        for (Map<String, Object> row : rows)
        {
            Object extension = row.get("extensionMeasurementsJson");
            if (extension != null) row.put("relativeTimeSeconds",
                    com.alibaba.fastjson2.JSON.parseObject(extension.toString()).get("relativeTimeSeconds"));
        }
        return rows;
    }
 
    /** 查询尚存工步记录,包含设备统计与授权历史导入。 */
    @Override public List<Map<String, Object>> steps(Long testId)
    {
        tests.selectTestById(testId);
        List<Map<String, Object>> rows = normalizeApiTimes(mapper.selectPersistedFinalStepRecords(testId));
        for (Map<String, Object> row : rows)
        {
            Object extension = row.get("extensionMeasurementsJson");
            if (extension == null) continue;
            Map<String, Object> values = com.alibaba.fastjson2.JSON.parseObject(extension.toString());
            // 中值与历史峰谷值是不同测量,不将旧扩展字段回退映射为中值。
            // 四组容量能量是设备工步层事实:单项列无法表达未确认方向时,调用方读这四组核对。
            for (String field : List.of("stepDuration", "startVoltage", "chargeMedianVoltage", "dischargeMedianVoltage",
                    "chargeCapacity", "dischargeCapacity", "chargeEnergy", "dischargeEnergy"))
                if (values.containsKey(field)) row.put(field, values.get(field));
        }
        return rows;
    }
 
    /** 查询尚存循环记录,包含设备统计、工步层聚合与授权历史导入;携带来源类别供界面标注聚合来源。 */
    @Override public List<Map<String, Object>> cycles(Long testId)
    {
        tests.selectTestById(testId);
        return normalizeApiTimes(mapper.selectPersistedFinalCycleRecords(testId));
    }
 
    private List<Map<String, Object>> normalizeApiTimes(List<Map<String, Object>> rows)
    {
        if (rows == null) return List.of();
        // DATETIME(3) 保存 UTC,JDBC 返回的无时区值也必须按 UTC 转换,不能采用服务器默认时区。
        for (Map<String, Object> row : rows)
            row.replaceAll((key, value) -> value instanceof Date date ? date.getTime()
                    : value instanceof Instant instant ? instant.toEpochMilli()
                    : value instanceof LocalDateTime time ? time.toInstant(ZoneOffset.UTC).toEpochMilli() : value);
        return rows;
    }
}