| | |
| | | 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.TTestLogicStepMapping; |
| | | import com.ruoyi.system.domain.TTestConsoleDetail; |
| | |
| | | import com.ruoyi.system.domain.vo.TestConfigurationOptionsVo; |
| | | import com.ruoyi.system.mapper.TTestMapper; |
| | | import com.ruoyi.system.service.ITTestService; |
| | | import com.ruoyi.system.service.ISharedFieldSnapshotService; |
| | | |
| | | /** 测试配置服务,负责状态边界、关系校验、事务写入和只追加审计。 */ |
| | | @Service |
| | |
| | | |
| | | @Autowired |
| | | private TTestMapper testMapper; |
| | | |
| | | @Autowired |
| | | private ISharedFieldSnapshotService sharedFieldSnapshotService; |
| | | |
| | | @Override |
| | | public TTest selectTestById(Long testId) |
| | |
| | | validateConfiguration(test); |
| | | test.setTestStatus(WAITING); |
| | | test.setReceptionStatus(NOT_STARTED); |
| | | test.setFieldSnapshots(sharedFieldSnapshotService.createForBatteryGroup( |
| | | test.getBatteries().get(0).getGroupId())); |
| | | test.setDelFlag("0"); |
| | | test.setCreateTime(new Date()); |
| | | testMapper.insertTest(test); |
| | | saveConfiguration(test); |
| | | testMapper.insertTestAudit(test.getTestId(), "TEST_CREATED", test.getOperatorId(), test.getCreateBy(), |
| | | null, JSON.toJSONString(test)); |
| | | // 最终基线移除了 t_test_audit;Controller 的 @Log 负责记录创建操作,业务表只保存配置事实。 |
| | | return test.getTestId(); |
| | | } |
| | | |
| | |
| | | test.setMonitorTimeoutMinutes(current.getMonitorTimeoutMinutes()); |
| | | validateBase(test, true); |
| | | validateConfiguration(test); |
| | | Long currentGroupId = current.getBatteries().isEmpty() ? null : current.getBatteries().get(0).getGroupId(); |
| | | Long nextGroupId = test.getBatteries().get(0).getGroupId(); |
| | | test.setFieldSnapshots(sharedFieldSnapshotService.resolveForUpdate( |
| | | currentGroupId, nextGroupId, current.getFieldSnapshots())); |
| | | test.setUpdateTime(new Date()); |
| | | int rows = testMapper.updateTest(test); |
| | | if (rows != 1) throw new ServiceException("测试配置已变更,请刷新后重试"); |
| | | |
| | | // 开始接收前没有数据归属事实,配置关系可在同一事务内整体替换,审计记录仍只追加。 |
| | | // 开始接收前没有数据归属事实,配置关系可在同一事务内整体替换;操作审计由 Controller @Log 追加。 |
| | | testMapper.deleteTestCollectorChannelsByTestId(test.getTestId()); |
| | | testMapper.deleteTestBindingsByTestId(test.getTestId()); |
| | | testMapper.deleteTestPlanStepsByTestId(test.getTestId()); |
| | | testMapper.deleteTestFieldsByTestId(test.getTestId()); |
| | | testMapper.deleteTestBatteriesByTestId(test.getTestId()); |
| | | testMapper.deleteTestThresholdsByTestId(test.getTestId()); |
| | | sharedFieldSnapshotService.deleteByTestId(test.getTestId()); |
| | | saveConfiguration(test); |
| | | testMapper.insertTestAudit(test.getTestId(), "TEST_CONFIGURATION_UPDATED", test.getOperatorId(), |
| | | test.getUpdateBy(), JSON.toJSONString(current), JSON.toJSONString(test)); |
| | | return rows; |
| | | } |
| | | |
| | |
| | | if (current == null) throw new ServiceException("测试不存在"); |
| | | if (!NOT_STARTED.equals(current.getReceptionStatus())) throw new ServiceException("开始接收后不能删除测试"); |
| | | loadConfiguration(current); |
| | | // 测试整体删除是无痕例外:先清理全部测试绑定和阈值,再删除主记录,不写审计。 |
| | | testMapper.deleteTestCollectorChannelsByTestId(testId); |
| | | testMapper.deleteTestBindingsByTestId(testId); |
| | | testMapper.deleteTestThresholdRowsByTestId(testId); |
| | | testMapper.deleteTestBatteriesByTestId(testId); |
| | | int deleted = testMapper.deleteTestById(testId, updateBy); |
| | | if (deleted != 1) throw new ServiceException("测试配置已变更,请刷新后重试"); |
| | | testMapper.insertTestAudit(testId, "TEST_DELETED", operatorId, updateBy, |
| | | JSON.toJSONString(current), null); |
| | | rows += deleted; |
| | | } |
| | | return rows; |
| | |
| | | private void loadConfiguration(TTest test) |
| | | { |
| | | Long testId = test.getTestId(); |
| | | List<TTestPlanStep> loadedPlanSteps = testMapper.selectTestPlanSteps(testId); |
| | | List<TTestPlanStep> planSteps = loadedPlanSteps == null ? mutable(test.getPlanSteps()) : mutable(loadedPlanSteps); |
| | | for (TTestPlanStep step : planSteps) |
| | | { |
| | | try |
| | | { |
| | | step.setParameters(JSON.parseObject(step.getParametersJson())); |
| | | } |
| | | catch (JSONException exception) |
| | | { |
| | | throw new ServiceException("计划工步参数无法解析"); |
| | | } |
| | | } |
| | | |
| | | 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<TTestBatteryField> currentFields = testMapper.selectCurrentBatteryFields(testId); |
| | | Map<Long, List<TTestBatteryField>> fieldsByBattery = new HashMap<>(); |
| | | for (TTestBatteryField field : mutable(currentFields)) |
| | | fieldsByBattery.computeIfAbsent(field.getRelationId(), ignored -> new ArrayList<>()).add(field); |
| | | List<TTestCollectorChannel> loadedCollectorChannels = testMapper.selectTestCollectorChannels(testId); |
| | | List<TTestCollectorChannel> collectorChannels = loadedCollectorChannels == null ? List.of() : mutable(loadedCollectorChannels); |
| | | Map<Long, TTestChannelBinding> bindings = new HashMap<>(); |
| | |
| | | for (TTestBattery battery : batteries) |
| | | { |
| | | battery.setBinding(bindings.get(battery.getRelationId())); |
| | | if (loadedFields != null && (!loadedFields.isEmpty() || battery.getFields() == null)) |
| | | battery.setFields(fields.stream() |
| | | .filter(field -> battery.getRelationId().equals(field.getRelationId())) |
| | | .toList()); |
| | | battery.setFields(fieldsByBattery.getOrDefault(battery.getRelationId(), List.of())); |
| | | 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)); |
| | | 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); |
| | | // 测试不保存字段快照;字段值始终随电池组当前配置读取。 |
| | | test.setFieldSnapshots(new ArrayList<>()); |
| | | String mappingJson = test.getLogicStepMappingsJson(); |
| | | try { test.setLogicStepMappings(mappingJson == null || mappingJson.isBlank() |
| | | ? new ArrayList<>() : JSON.parseArray(mappingJson, TTestLogicStepMapping.class)); } |
| | |
| | | |
| | | private void validateConfiguration(TTest test) |
| | | { |
| | | // 新建测试只建立业务身份和通道关系,计划工步可在开始接收前补充。 |
| | | if (test.getPlanSteps() == null) test.setPlanSteps(new ArrayList<>()); |
| | | // 计划工步来自设备观测,不属于测试创建配置,也不写入业务库。 |
| | | test.setPlanSteps(new ArrayList<>()); |
| | | validateBatteries(test.getBatteries()); |
| | | validatePlanSteps(test.getPlanSteps()); |
| | | validateThresholds(test.getThresholds()); |
| | |
| | | |
| | | private void saveConfiguration(TTest test) |
| | | { |
| | | for (TTestPlanStep step : test.getPlanSteps()) |
| | | { |
| | | step.setTestId(test.getTestId()); |
| | | testMapper.insertTestPlanStep(step); |
| | | } |
| | | for (TTestBattery battery : test.getBatteries()) |
| | | { |
| | | battery.setTestId(test.getTestId()); |
| | | testMapper.insertTestBattery(battery); |
| | | if (battery.getFields() != null) |
| | | { |
| | | for (TTestBatteryField field : battery.getFields()) |
| | | { |
| | | field.setRelationId(battery.getRelationId()); |
| | | testMapper.insertTestBatteryField(field); |
| | | } |
| | | } |
| | | TTestChannelBinding binding = battery.getBinding(); |
| | | binding.setTestId(test.getTestId()); |
| | | binding.setBatteryRelationId(battery.getRelationId()); |
| | |
| | | testMapper.insertTestCollectorChannel(mapping); |
| | | } |
| | | } |
| | | sharedFieldSnapshotService.saveForTest(test.getTestId(), test.getFieldSnapshots()); |
| | | for (TTestWarningThreshold threshold : test.getThresholds()) |
| | | { |
| | | threshold.setTestId(test.getTestId()); |