| | |
| | | { |
| | | private static final String WAITING = "WAITING"; |
| | | private static final String NOT_STARTED = "NOT_STARTED"; |
| | | private static final Set<String> TEST_STATUSES = Set.of( |
| | | WAITING, "RUNNING", "PAUSED", "RUNNING_ABNORMAL", "COMPLETION_PENDING", "COMPLETED", "TERMINATED"); |
| | | /** 新流程只允许四种测试状态;历史状态仅在旧数据展示层做兼容映射。 */ |
| | | private static final Set<String> TEST_STATUSES = Set.of(WAITING, "RUNNING", "PAUSED", "COMPLETED"); |
| | | private static final Set<String> RECEPTION_STATUSES = Set.of(NOT_STARTED, "RECEIVING", "PAUSED", "ENDED"); |
| | | private static final Set<String> THRESHOLD_UNITS = Set.of("A", "V", "Ah", "Wh", "℃"); |
| | | private static final Set<String> REQUIRED_COLLECTOR_MEASUREMENTS = Set.of( |
| | |
| | | TTest current = testMapper.selectTestByIdForUpdate(test.getTestId()); |
| | | if (current == null) throw new ServiceException("测试不存在"); |
| | | loadConfiguration(current); |
| | | if (!NOT_STARTED.equals(current.getReceptionStatus())) |
| | | if (!stateMatches(current, WAITING, NOT_STARTED)) |
| | | throw new ServiceException("开始接收后不能修改测试配置"); |
| | | |
| | | test.setCreatorId(current.getCreatorId()); |
| | |
| | | if (operatorId == null) throw new ServiceException("操作人不能为空"); |
| | | TTest current = testMapper.selectTestByIdForUpdate(testId); |
| | | if (current == null) throw new ServiceException("测试不存在"); |
| | | if (!NOT_STARTED.equals(current.getReceptionStatus())) |
| | | if (!stateMatches(current, WAITING, NOT_STARTED)) |
| | | throw new ServiceException("当前测试不是未开始接收状态"); |
| | | loadConfiguration(current); |
| | | if (current.getBatteries().isEmpty()) throw new ServiceException("测试未配置电池号"); |
| | |
| | | if (channel == null || !isEnabled(channel.getStatus())) |
| | | throw new ServiceException("检测柜通道 " + binding.getChannelId() + " 不存在或未启用"); |
| | | // 只有设备事实为运行中时才标记“运行中接入”;设备暂停属于独立设备状态。 |
| | | runtimeAttach |= "WORKING".equalsIgnoreCase(channel.getWorkStatus()); |
| | | runtimeAttach |= "WORKING".equalsIgnoreCase(channel.getWorkStatus()) |
| | | || "RUNNING".equalsIgnoreCase(channel.getWorkStatus()); |
| | | if (battery.getCollectorId() == null || testMapper.countCollectorEnabled(battery.getCollectorId()) == 0) |
| | | throw new ServiceException("电池号 " + battery.getBatteryNo() + " 的采集器不存在或未启用"); |
| | | Integer collectorChannelCount = testMapper.selectCollectorChannelCount(battery.getCollectorId()); |
| | |
| | | if (operatorId == null) throw new ServiceException("操作人不能为空"); |
| | | TTest current = testMapper.selectTestByIdForUpdate(testId); |
| | | if (current == null) throw new ServiceException("测试不存在"); |
| | | if (!"RECEIVING".equals(current.getReceptionStatus())) |
| | | if (!stateMatches(current, "RUNNING", "RECEIVING")) |
| | | throw new ServiceException("当前测试不是接收中状态"); |
| | | |
| | | Date actionAt = new Date(); |
| | |
| | | if (operatorId == null) throw new ServiceException("操作人不能为空"); |
| | | TTest current = testMapper.selectTestByIdForUpdate(testId); |
| | | if (current == null) throw new ServiceException("测试不存在"); |
| | | if (!"PAUSED".equals(current.getReceptionStatus())) |
| | | if (!stateMatches(current, "PAUSED", "PAUSED")) |
| | | throw new ServiceException("当前测试不是暂停接收状态"); |
| | | // 加锁查询只返回测试主表,继续接收前重新加载绑定配置以校验来源仍可用。 |
| | | loadConfiguration(current); |
| | |
| | | if (operatorId == null) throw new ServiceException("操作人不能为空"); |
| | | TTest current = testMapper.selectTestByIdForUpdate(testId); |
| | | if (current == null) throw new ServiceException("测试不存在"); |
| | | if (NOT_STARTED.equals(current.getReceptionStatus()) || "ENDED".equals(current.getReceptionStatus())) |
| | | if (!(stateMatches(current, "RUNNING", "RECEIVING") |
| | | || stateMatches(current, "PAUSED", "PAUSED"))) |
| | | throw new ServiceException("当前测试不能停止"); |
| | | Date actionAt = new Date(); |
| | | if (testMapper.updateReceptionStopped(testId, updateBy, actionAt) != 1) |
| | |
| | | return status == null || "0".equals(status); |
| | | } |
| | | |
| | | /** 生命周期动作必须同时匹配测试状态和接收状态,避免并发请求后两个状态字段互相矛盾。 */ |
| | | private boolean stateMatches(TTest test, String expectedTestStatus, String expectedReceptionStatus) |
| | | { |
| | | return expectedReceptionStatus.equals(test.getReceptionStatus()) |
| | | && expectedTestStatus.equals(test.getTestStatus()); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int deleteTestByIds(Long[] testIds, Long operatorId, String updateBy) |
| | |
| | | { |
| | | TTest current = testMapper.selectTestByIdForUpdate(testId); |
| | | if (current == null) throw new ServiceException("测试不存在"); |
| | | if (!NOT_STARTED.equals(current.getReceptionStatus())) throw new ServiceException("开始接收后不能删除测试"); |
| | | if (!stateMatches(current, WAITING, NOT_STARTED)) throw new ServiceException("开始接收后不能删除测试"); |
| | | loadConfiguration(current); |
| | | // 测试整体删除是无痕例外:先清理全部测试绑定和阈值,再删除主记录,不写审计。 |
| | | testMapper.deleteTestCollectorChannelsByTestId(testId); |