package com.ruoyi.system.service.impl;
|
|
import java.math.BigDecimal;
|
import java.nio.charset.StandardCharsets;
|
import java.security.MessageDigest;
|
import java.util.Date;
|
import java.util.HexFormat;
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.Optional;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import com.ruoyi.device.bts.BtsDevelopmentSimulator;
|
import com.ruoyi.device.simulator.BtsSimulatorStateStore.BtsHistoryRecord;
|
import com.ruoyi.system.domain.TTest;
|
import com.ruoyi.system.domain.TTestBattery;
|
import com.ruoyi.system.domain.TTestChannelBinding;
|
import com.ruoyi.system.domain.TTestReceptionInterval;
|
import com.ruoyi.system.mapper.TTestMapper;
|
import com.ruoyi.system.service.ITTestService;
|
import com.ruoyi.system.service.ITestDataReceptionService;
|
|
/** 接收时确定测试归属,并以现有采样表追加保存检测柜事实。 */
|
@Service
|
public class TestDataReceptionServiceImpl implements ITestDataReceptionService
|
{
|
private final TTestMapper mapper;
|
private final ITTestService tests;
|
private final BtsDevelopmentSimulator simulator;
|
|
public TestDataReceptionServiceImpl(TTestMapper mapper, ITTestService tests, BtsDevelopmentSimulator simulator)
|
{
|
this.mapper = mapper;
|
this.tests = tests;
|
this.simulator = simulator;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void captureDevelopmentCabinetRecords()
|
{
|
List<Long> testIds = mapper.selectReceivingTestIds();
|
if (testIds == null) return;
|
for (Long testId : testIds)
|
{
|
TTest test = tests.selectTestById(testId);
|
if (test == null || !"RECEIVING".equals(test.getReceptionStatus())) continue;
|
captureTest(test);
|
}
|
}
|
|
private void captureTest(TTest test)
|
{
|
for (TTestBattery battery : test.getBatteries() == null ? List.<TTestBattery>of() : test.getBatteries())
|
{
|
TTestChannelBinding binding = battery.getBinding();
|
if (binding == null || binding.getDevid() == null || binding.getChlid() == null) continue;
|
Optional<TTestReceptionInterval> open = mapper.selectTestReceptionIntervals(test.getTestId()).stream()
|
.filter(item -> Objects.equals(item.getBindingId(), binding.getBindingId())
|
&& "CABINET_CHANNEL".equals(item.getSourceType())
|
&& Objects.equals(item.getSourceId(), binding.getChannelId())
|
&& "OPEN".equals(item.getIntervalStatus()))
|
.findFirst();
|
if (open.isEmpty()) continue;
|
Date start = open.get().getStartBoundaryAtUtc();
|
List<BtsHistoryRecord> records;
|
try { records = simulator.btsRecords(binding.getDevid(), binding.getChlid()); }
|
catch (IllegalArgumentException ignored) { continue; }
|
for (BtsHistoryRecord record : records)
|
{
|
if (start != null && record.deviceTime().isBefore(start.toInstant())) continue;
|
save(test, battery, binding, open.get(), record);
|
}
|
}
|
}
|
|
private void save(TTest test, TTestBattery battery, TTestChannelBinding binding,
|
TTestReceptionInterval interval, BtsHistoryRecord record)
|
{
|
// 模拟器历史 testid 按通道固定;接收事实必须再带测试作用域,避免顺序测试共用全局幂等键。
|
String btsTestId = "SIM-" + binding.getDevid() + "-" + binding.getChlid() + "-T" + test.getTestId();
|
byte[] hash = hash(record);
|
String old = mapper.selectSampleContentHash(binding.getChannelId(), btsTestId, record.sequenceId());
|
if (old != null)
|
{
|
if (!old.equalsIgnoreCase(HexFormat.of().formatHex(hash)))
|
mapper.insertBackfillConflict(test.getTestId(), binding.getChannelId(),
|
"实时接收内容冲突 testid=" + btsTestId + ", seqid=" + record.sequenceId());
|
return;
|
}
|
mapper.insertBtsSample(test.getTestId(), binding.getBindingId(), binding.getChannelId(), interval.getIntervalId(),
|
btsTestId, record.sequenceId(), Date.from(record.deviceTime()),
|
record.deviceTime().toString(), new Date(), record.cycleNo(), record.stepNo(), record.stepType(),
|
record.stepName(), null,
|
BigDecimal.valueOf(record.voltageV()), BigDecimal.valueOf(record.currentA()),
|
BigDecimal.valueOf(record.capacityAh()), BigDecimal.valueOf(record.energyWh()), hash);
|
}
|
|
private byte[] hash(BtsHistoryRecord record)
|
{
|
try
|
{
|
String value = record.sequenceId() + "|" + record.deviceTime() + "|" + record.currentA() + "|"
|
+ record.voltageV() + "|" + record.capacityAh() + "|" + record.energyWh() + "|"
|
+ record.cycleNo() + "|" + record.stepNo() + "|" + record.stepType();
|
return MessageDigest.getInstance("SHA-256").digest(value.getBytes(StandardCharsets.UTF_8));
|
}
|
catch (Exception exception) { throw new IllegalStateException("无法计算采样内容摘要", exception); }
|
}
|
}
|