From a2a8908f2d9d4e19201423ff58ee23c65a8df670 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期六, 29 八月 2026 20:51:10 +0800
Subject: [PATCH] 实现测试原子开始接收
---
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTestServiceImpl.java | 147 ++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 133 insertions(+), 14 deletions(-)
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTestServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTestServiceImpl.java
index d077b3d..e2fedad 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTestServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTestServiceImpl.java
@@ -10,6 +10,7 @@
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
@@ -21,7 +22,10 @@
import com.ruoyi.system.domain.TTestCollectorChannel;
import com.ruoyi.system.domain.TTestPlanStep;
import com.ruoyi.system.domain.TTestResult;
+import com.ruoyi.system.domain.TTestFieldSnapshot;
import com.ruoyi.system.domain.TTestWarningThreshold;
+import com.ruoyi.system.domain.TDetectionChannel;
+import com.ruoyi.system.domain.TTestReceptionInterval;
import com.ruoyi.system.domain.vo.TestConfigurationOptionsVo;
import com.ruoyi.system.mapper.TTestMapper;
import com.ruoyi.system.service.ITTestService;
@@ -146,7 +150,109 @@
@Override
public int startTest(Long testId, String updateBy)
{
- throw new ServiceException("开始接收由后续原子动作处理");
+ throw new ServiceException("旧开始入口已停用,请使用原子开始接收接口并提供操作人");
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public int startReception(Long testId, Long operatorId, String updateBy)
+ {
+ if (testId == null) throw new ServiceException("测试ID不能为空");
+ if (operatorId == null) throw new ServiceException("操作人不能为空");
+ TTest current = testMapper.selectTestByIdForUpdate(testId);
+ if (current == null) throw new ServiceException("测试不存在");
+ if (!NOT_STARTED.equals(current.getReceptionStatus()))
+ throw new ServiceException("当前测试不是未开始接收状态");
+ loadConfiguration(current);
+ if (current.getBatteries().isEmpty()) throw new ServiceException("测试未配置电池号");
+
+ Date actionAt = new Date();
+ List<TTestReceptionInterval> intervals = new ArrayList<>();
+ Set<Long> channelIds = new HashSet<>();
+ Set<String> collectorChannels = new HashSet<>();
+ boolean runtimeAttach = false;
+ for (TTestBattery battery : current.getBatteries())
+ {
+ TTestChannelBinding binding = battery.getBinding();
+ if (binding == null || binding.getChannelId() == null)
+ throw new ServiceException("电池号 " + battery.getBatteryNo() + " 未绑定检测柜通道");
+ if (!channelIds.add(binding.getChannelId()))
+ throw new ServiceException("检测柜通道重复绑定,无法开始接收");
+ TDetectionChannel channel = testMapper.selectReceptionChannelForUpdate(binding.getChannelId());
+ if (channel == null || !isEnabled(channel.getStatus()) || !isOnline(channel.getOnlineStatus()))
+ throw new ServiceException("检测柜通道 " + binding.getChannelId() + " 当前离线或不可观测");
+ if (channel.getLastSeenAtUtc() == null)
+ throw new ServiceException("检测柜通道 " + binding.getChannelId() + " 尚未取得成功观测边界");
+ runtimeAttach |= "WORKING".equalsIgnoreCase(channel.getWorkStatus())
+ || "PAUSED".equalsIgnoreCase(channel.getWorkStatus());
+ if (testMapper.selectChannelLeaseForUpdate(binding.getChannelId()) != null)
+ throw new ServiceException("检测柜通道 " + binding.getChannelId() + " 已被其他测试占用");
+ if (battery.getCollectorId() == null || testMapper.countCollectorEnabled(battery.getCollectorId()) == 0)
+ throw new ServiceException("电池号 " + battery.getBatteryNo() + " 的采集器不存在或未启用");
+ if (!testMapper.collectorOnline(battery.getCollectorId()))
+ throw new ServiceException("采集器 " + battery.getCollectorId() + " 当前离线或不可观测");
+ Integer collectorChannelCount = testMapper.selectCollectorChannelCount(battery.getCollectorId());
+ validateCollectorChannels(battery.getCollectorId(), collectorChannelCount == null ? 0 : collectorChannelCount,
+ battery.getCollectorChannels(), collectorChannels);
+
+ intervals.add(interval(current, binding.getBindingId(), "CABINET_CHANNEL", binding.getChannelId(), null,
+ actionAt, Date.from(channel.getLastSeenAtUtc()), runtimeAttach
+ ? "运行中接入:采用检测柜最近成功观测边界" : "采用检测柜最近成功观测边界"));
+ for (TTestCollectorChannel mapping : mutable(battery.getCollectorChannels()))
+ {
+ intervals.add(interval(current, binding.getBindingId(), "COLLECTOR_CHANNEL", battery.getCollectorId(),
+ mapping.getChannelCode(), actionAt, actionAt, "采集器开始接收确认边界"));
+ }
+ }
+
+ try
+ {
+ for (TTestBattery battery : current.getBatteries())
+ {
+ TTestChannelBinding binding = battery.getBinding();
+ testMapper.insertChannelLease(binding.getChannelId(), testId, binding.getBindingId(), operatorId, actionAt);
+ for (TTestCollectorChannel mapping : mutable(battery.getCollectorChannels()))
+ testMapper.insertCollectorChannelLease(battery.getCollectorId(), mapping.getChannelCode(), testId,
+ binding.getBindingId(), operatorId, actionAt);
+ }
+ for (TTestReceptionInterval interval : intervals) testMapper.insertReceptionInterval(interval);
+ if (testMapper.updateReceptionStarted(testId, actionAt, updateBy) != 1)
+ throw new ServiceException("测试状态已变更,请刷新后重试");
+ testMapper.insertTestAudit(testId, "RECEPTION_STARTED", operatorId, updateBy, null,
+ JSON.toJSONString(Map.of("receptionStatus", "RECEIVING", "intervalCount", intervals.size(),
+ "runtimeAttach", runtimeAttach, "intervals", intervals)));
+ return 1;
+ }
+ catch (DuplicateKeyException exception)
+ {
+ throw new ServiceException("数据来源已被其他测试占用,请刷新后重试");
+ }
+ }
+
+ private TTestReceptionInterval interval(TTest test, Long bindingId, String sourceType, Long sourceId,
+ String sourceChannelCode, Date actionAt, Date boundaryAt, String note)
+ {
+ TTestReceptionInterval interval = new TTestReceptionInterval();
+ interval.setTestId(test.getTestId());
+ interval.setBindingId(bindingId);
+ interval.setSourceType(sourceType);
+ interval.setSourceId(sourceId);
+ interval.setSourceChannelCode(sourceChannelCode);
+ interval.setActionAtUtc(actionAt);
+ interval.setStartBoundaryAtUtc(boundaryAt);
+ interval.setBoundaryNote(note);
+ interval.setIntervalStatus("OPEN");
+ return interval;
+ }
+
+ private boolean isOnline(String status)
+ {
+ return status != null && ("ONLINE".equalsIgnoreCase(status) || "0".equals(status));
+ }
+
+ private boolean isEnabled(String status)
+ {
+ return status == null || "0".equals(status);
}
@Override
@@ -181,7 +287,8 @@
private void loadConfiguration(TTest test)
{
Long testId = test.getTestId();
- List<TTestPlanStep> planSteps = mutable(testMapper.selectTestPlanSteps(testId));
+ List<TTestPlanStep> loadedPlanSteps = testMapper.selectTestPlanSteps(testId);
+ List<TTestPlanStep> planSteps = loadedPlanSteps == null ? mutable(test.getPlanSteps()) : mutable(loadedPlanSteps);
for (TTestPlanStep step : planSteps)
{
try
@@ -194,27 +301,39 @@
}
}
- List<TTestBattery> batteries = mutable(testMapper.selectTestBatteries(testId));
- List<TTestBatteryField> fields = mutable(testMapper.selectTestBatteryFields(testId));
- List<TTestCollectorChannel> collectorChannels = mutable(testMapper.selectTestCollectorChannels(testId));
+ List<TTestBattery> loadedBatteries = testMapper.selectTestBatteries(testId);
+ List<TTestBattery> batteries = loadedBatteries == null || (loadedBatteries.isEmpty() && test.getBatteries() != null
+ && !test.getBatteries().isEmpty()) ? mutable(test.getBatteries()) : mutable(loadedBatteries);
+ List<TTestBatteryField> loadedFields = testMapper.selectTestBatteryFields(testId);
+ List<TTestBatteryField> fields = loadedFields == null ? List.of() : mutable(loadedFields);
+ List<TTestCollectorChannel> loadedCollectorChannels = testMapper.selectTestCollectorChannels(testId);
+ List<TTestCollectorChannel> collectorChannels = loadedCollectorChannels == null ? List.of() : mutable(loadedCollectorChannels);
Map<Long, TTestChannelBinding> bindings = new HashMap<>();
- for (TTestChannelBinding binding : mutable(testMapper.selectTestChannelBindings(testId)))
+ List<TTestChannelBinding> loadedBindings = testMapper.selectTestChannelBindings(testId);
+ if (loadedBindings == null || (loadedBindings.isEmpty() && batteries.stream().anyMatch(item -> item.getBinding() != null)))
+ for (TTestBattery battery : batteries)
+ if (battery.getBinding() != null) bindings.put(battery.getRelationId(), battery.getBinding());
+ for (TTestChannelBinding binding : mutable(loadedBindings))
bindings.put(binding.getBatteryRelationId(), binding);
for (TTestBattery battery : batteries)
{
battery.setBinding(bindings.get(battery.getRelationId()));
- battery.setFields(fields.stream()
- .filter(field -> battery.getRelationId().equals(field.getRelationId()))
- .toList());
- battery.setCollectorChannels(collectorChannels.stream()
- .filter(mapping -> battery.getRelationId().equals(mapping.getBatteryRelationId()))
- .toList());
+ if (loadedFields != null && (!loadedFields.isEmpty() || battery.getFields() == null))
+ battery.setFields(fields.stream()
+ .filter(field -> battery.getRelationId().equals(field.getRelationId()))
+ .toList());
+ if (loadedCollectorChannels != null && (!loadedCollectorChannels.isEmpty() || battery.getCollectorChannels() == null))
+ battery.setCollectorChannels(collectorChannels.stream()
+ .filter(mapping -> battery.getRelationId().equals(mapping.getBatteryRelationId()))
+ .toList());
}
test.setPlanSteps(planSteps);
test.setBatteries(batteries);
test.setBatteryNo(joinBatteryNos(batteries));
- test.setThresholds(mutable(testMapper.selectTestThresholds(testId)));
- test.setFieldSnapshots(sharedFieldSnapshotService.selectByTestId(testId));
+ List<TTestWarningThreshold> loadedThresholds = testMapper.selectTestThresholds(testId);
+ test.setThresholds(loadedThresholds == null ? mutable(test.getThresholds()) : mutable(loadedThresholds));
+ List<TTestFieldSnapshot> loadedSnapshots = sharedFieldSnapshotService.selectByTestId(testId);
+ test.setFieldSnapshots(loadedSnapshots == null ? mutable(test.getFieldSnapshots()) : loadedSnapshots);
}
private void validateBase(TTest test, boolean update)
--
Gitblit v1.7.1