修正共享字段快照模块边界
将测试字段快照规则和持久化收口到共享字段服务。
移除 MySQL 专有电池号聚合并补充批量查询与自动化测试。
| | |
| | | package com.ruoyi.config; |
| | | |
| | | import static org.junit.jupiter.api.Assertions.assertTrue; |
| | | import static org.junit.jupiter.api.Assertions.assertFalse; |
| | | |
| | | import java.io.InputStream; |
| | | import java.nio.charset.StandardCharsets; |
| | |
| | | void persistsAndReadsCollectorMappingsAndFieldSnapshots() |
| | | { |
| | | String mapper = resource("mapper/system/TTestMapper.xml"); |
| | | String snapshotMapper = resource("mapper/system/TSharedFieldSnapshotMapper.xml"); |
| | | |
| | | assertTrue(mapper.contains("id=\"insertTestCollectorChannel\"")); |
| | | assertTrue(mapper.contains("id=\"selectTestCollectorChannels\"")); |
| | | assertTrue(mapper.contains("id=\"insertTestFieldSnapshot\"")); |
| | | assertTrue(mapper.contains("id=\"selectTestFieldSnapshots\"")); |
| | | assertTrue(snapshotMapper.contains("id=\"insert\"")); |
| | | assertTrue(snapshotMapper.contains("id=\"selectByTestId\"")); |
| | | assertTrue(mapper.contains("reception_status = 'NOT_STARTED'")); |
| | | assertTrue(mapper.contains("channel_count channelCount")); |
| | | assertTrue(mapper.contains("id=\"selectBatteryNosByTestIds\"")); |
| | | assertFalse(mapper.contains("group_concat")); |
| | | } |
| | | |
| | | private static String resource(String path) |
| New file |
| | |
| | | package com.ruoyi.system.service.impl; |
| | | |
| | | import static org.junit.jupiter.api.Assertions.assertEquals; |
| | | import static org.junit.jupiter.api.Assertions.assertNotSame; |
| | | import static org.mockito.Mockito.never; |
| | | import static org.mockito.Mockito.verify; |
| | | import static org.mockito.Mockito.when; |
| | | |
| | | import java.util.List; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.junit.jupiter.api.extension.ExtendWith; |
| | | import org.mockito.InjectMocks; |
| | | import org.mockito.Mock; |
| | | import org.mockito.junit.jupiter.MockitoExtension; |
| | | import com.ruoyi.system.domain.TBatteryGroup; |
| | | import com.ruoyi.system.domain.TBatteryGroupRelationField; |
| | | import com.ruoyi.system.domain.TTestFieldSnapshot; |
| | | import com.ruoyi.system.mapper.TSharedFieldSnapshotMapper; |
| | | import com.ruoyi.system.service.ITBatteryGroupService; |
| | | |
| | | /** 共享业务字段快照规则测试。 */ |
| | | @ExtendWith(MockitoExtension.class) |
| | | class TSharedFieldSnapshotServiceImplTest |
| | | { |
| | | @Mock |
| | | private ITBatteryGroupService batteryGroupService; |
| | | |
| | | @Mock |
| | | private TSharedFieldSnapshotMapper snapshotMapper; |
| | | |
| | | @InjectMocks |
| | | private TSharedFieldSnapshotServiceImpl snapshotService; |
| | | |
| | | @Test |
| | | void createShouldCopyActiveBatteryGroupFields() |
| | | { |
| | | when(batteryGroupService.selectBatteryGroupById(1L)).thenReturn(group("72")); |
| | | |
| | | List<TTestFieldSnapshot> snapshots = snapshotService.createForBatteryGroup(1L); |
| | | |
| | | assertEquals(1, snapshots.size()); |
| | | assertEquals(11L, snapshots.get(0).getFieldDefinitionId()); |
| | | assertEquals("额定容量", snapshots.get(0).getFieldName()); |
| | | assertEquals("number", snapshots.get(0).getFieldType()); |
| | | assertEquals("72", snapshots.get(0).getFieldValue()); |
| | | } |
| | | |
| | | @Test |
| | | void sameGroupUpdateShouldRetainOriginalSnapshotValue() |
| | | { |
| | | TTestFieldSnapshot original = snapshot("72"); |
| | | |
| | | List<TTestFieldSnapshot> resolved = snapshotService.resolveForUpdate(1L, 1L, List.of(original)); |
| | | |
| | | assertEquals("72", resolved.get(0).getFieldValue()); |
| | | assertNotSame(original, resolved.get(0)); |
| | | verify(batteryGroupService, never()).selectBatteryGroupById(1L); |
| | | } |
| | | |
| | | @Test |
| | | void changingGroupShouldCreateSnapshotFromNewGroup() |
| | | { |
| | | when(batteryGroupService.selectBatteryGroupById(2L)).thenReturn(group("99")); |
| | | |
| | | List<TTestFieldSnapshot> resolved = snapshotService.resolveForUpdate(1L, 2L, List.of(snapshot("72"))); |
| | | |
| | | assertEquals("99", resolved.get(0).getFieldValue()); |
| | | verify(batteryGroupService).selectBatteryGroupById(2L); |
| | | } |
| | | |
| | | private TBatteryGroup group(String value) |
| | | { |
| | | TBatteryGroupRelationField field = new TBatteryGroupRelationField(); |
| | | field.setBatteryGroupFieldId(11L); |
| | | field.setFieldName("额定容量"); |
| | | field.setFieldType("number"); |
| | | field.setFieldValue(value); |
| | | TBatteryGroup group = new TBatteryGroup(); |
| | | group.setTemplateFields(List.of(field)); |
| | | return group; |
| | | } |
| | | |
| | | private TTestFieldSnapshot snapshot(String value) |
| | | { |
| | | TTestFieldSnapshot snapshot = new TTestFieldSnapshot(); |
| | | snapshot.setFieldDefinitionId(11L); |
| | | snapshot.setFieldName("额定容量"); |
| | | snapshot.setFieldType("number"); |
| | | snapshot.setFieldValue(value); |
| | | return snapshot; |
| | | } |
| | | } |
| | |
| | | import org.mockito.junit.jupiter.MockitoExtension; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.system.domain.TTest; |
| | | import com.ruoyi.system.domain.TBatteryGroup; |
| | | import com.ruoyi.system.domain.TBatteryGroupRelationField; |
| | | import com.ruoyi.system.domain.TTestBattery; |
| | | import com.ruoyi.system.domain.TTestChannelBinding; |
| | | import com.ruoyi.system.domain.TTestCollectorChannel; |
| | |
| | | import com.ruoyi.system.domain.TTestPlanStep; |
| | | import com.ruoyi.system.domain.TTestWarningThreshold; |
| | | import com.ruoyi.system.mapper.TTestMapper; |
| | | import com.ruoyi.system.service.ITBatteryGroupService; |
| | | import com.ruoyi.system.service.ISharedFieldSnapshotService; |
| | | |
| | | /** 测试配置服务的业务契约测试。 */ |
| | | @ExtendWith(MockitoExtension.class) |
| | |
| | | private TTestMapper testMapper; |
| | | |
| | | @Mock |
| | | private ITBatteryGroupService batteryGroupService; |
| | | private ISharedFieldSnapshotService sharedFieldSnapshotService; |
| | | |
| | | @InjectMocks |
| | | private TTestServiceImpl testService; |
| | |
| | | verify(testMapper).insertTestPlanStep(any(TTestPlanStep.class)); |
| | | verify(testMapper).insertTestChannelBinding(any(TTestChannelBinding.class)); |
| | | verify(testMapper, times(3)).insertTestCollectorChannel(any(TTestCollectorChannel.class)); |
| | | verify(testMapper).insertTestFieldSnapshot(any()); |
| | | verify(sharedFieldSnapshotService).saveForTest(eq(10L), any()); |
| | | verify(testMapper).insertTestThreshold(any(TTestWarningThreshold.class)); |
| | | verify(testMapper).insertTestAudit(anyLong(), any(), anyLong(), any(), isNull(), any()); |
| | | } |
| | | |
| | | @Test |
| | | void listShouldAggregateBatteryNumbersOutsideDatabaseQuery() |
| | | { |
| | | TTest first = new TTest(); |
| | | first.setTestId(10L); |
| | | TTest second = new TTest(); |
| | | second.setTestId(11L); |
| | | TTestBattery firstBattery = new TTestBattery(); |
| | | firstBattery.setTestId(10L); |
| | | firstBattery.setBatteryNo("BAT-001"); |
| | | TTestBattery secondBattery = new TTestBattery(); |
| | | secondBattery.setTestId(10L); |
| | | secondBattery.setBatteryNo("BAT-002"); |
| | | when(testMapper.selectTestList(any(TTest.class))).thenReturn(java.util.List.of(first, second)); |
| | | when(testMapper.selectBatteryNosByTestIds(java.util.List.of(10L, 11L))) |
| | | .thenReturn(java.util.List.of(firstBattery, secondBattery)); |
| | | |
| | | java.util.List<TTest> result = testService.selectTestList(new TTest()); |
| | | |
| | | assertEquals("BAT-001、BAT-002", result.get(0).getBatteryNo()); |
| | | assertEquals("", result.get(1).getBatteryNo()); |
| | | } |
| | | |
| | | @Test |
| | |
| | | current.setReceptionStatus("NOT_STARTED"); |
| | | current.setMonitorTimeoutMinutes(30); |
| | | when(testMapper.selectTestByIdForUpdate(10L)).thenReturn(current); |
| | | when(testMapper.selectTestBatteries(10L)).thenReturn(current.getBatteries()); |
| | | when(sharedFieldSnapshotService.selectByTestId(10L)).thenReturn(java.util.List.of()); |
| | | when(sharedFieldSnapshotService.resolveForUpdate(1L, 1L, java.util.List.of())) |
| | | .thenReturn(java.util.List.of()); |
| | | mockEnabledOptions(); |
| | | mockGroupSnapshot(); |
| | | when(testMapper.updateTest(request)).thenReturn(1); |
| | | doAnswer(invocation -> { |
| | | invocation.<TTestBattery>getArgument(0).setRelationId(21L); |
| | |
| | | |
| | | when(testMapper.selectTestByIdForUpdate(10L)).thenReturn(current); |
| | | when(testMapper.selectTestBatteries(10L)).thenReturn(current.getBatteries()); |
| | | when(testMapper.selectTestFieldSnapshots(10L)).thenReturn(java.util.List.of(originalSnapshot)); |
| | | when(sharedFieldSnapshotService.selectByTestId(10L)).thenReturn(java.util.List.of(originalSnapshot)); |
| | | when(sharedFieldSnapshotService.resolveForUpdate(1L, 1L, java.util.List.of(originalSnapshot))) |
| | | .thenReturn(java.util.List.of(originalSnapshot)); |
| | | mockEnabledOptions(); |
| | | when(testMapper.updateTest(request)).thenReturn(1); |
| | | doAnswer(invocation -> { |
| | |
| | | |
| | | assertEquals(1, testService.updateTest(request)); |
| | | |
| | | verify(testMapper).insertTestFieldSnapshot(org.mockito.ArgumentMatchers.argThat(snapshot -> |
| | | Long.valueOf(11L).equals(snapshot.getFieldDefinitionId()) |
| | | && "额定容量".equals(snapshot.getFieldName()) |
| | | && "number".equals(snapshot.getFieldType()) |
| | | && "72".equals(snapshot.getFieldValue()))); |
| | | verify(batteryGroupService, never()).selectBatteryGroupById(anyLong()); |
| | | verify(sharedFieldSnapshotService).resolveForUpdate(1L, 1L, java.util.List.of(originalSnapshot)); |
| | | verify(sharedFieldSnapshotService).saveForTest(eq(10L), org.mockito.ArgumentMatchers.argThat(snapshots -> |
| | | snapshots.size() == 1 && "72".equals(snapshots.get(0).getFieldValue()))); |
| | | } |
| | | |
| | | @Test |
| | |
| | | |
| | | private void mockGroupSnapshot() |
| | | { |
| | | TBatteryGroupRelationField field = new TBatteryGroupRelationField(); |
| | | field.setBatteryGroupFieldId(11L); |
| | | field.setFieldName("额定容量"); |
| | | field.setFieldType("number"); |
| | | field.setFieldValue("72"); |
| | | TBatteryGroup group = new TBatteryGroup(); |
| | | group.setGroupId(1L); |
| | | group.setTemplateFields(java.util.List.of(field)); |
| | | when(batteryGroupService.selectBatteryGroupById(1L)).thenReturn(group); |
| | | TTestFieldSnapshot snapshot = new TTestFieldSnapshot(); |
| | | snapshot.setFieldDefinitionId(11L); |
| | | snapshot.setFieldName("额定容量"); |
| | | snapshot.setFieldType("number"); |
| | | snapshot.setFieldValue("72"); |
| | | when(sharedFieldSnapshotService.createForBatteryGroup(1L)).thenReturn(java.util.List.of(snapshot)); |
| | | } |
| | | |
| | | private TTest validTest() |
| New file |
| | |
| | | package com.ruoyi.system.mapper; |
| | | |
| | | import java.util.List; |
| | | import com.ruoyi.system.domain.TTestFieldSnapshot; |
| | | |
| | | /** 共享业务字段快照持久层。 */ |
| | | public interface TSharedFieldSnapshotMapper |
| | | { |
| | | List<TTestFieldSnapshot> selectByTestId(Long testId); |
| | | int insert(TTestFieldSnapshot snapshot); |
| | | int deleteByTestId(Long testId); |
| | | } |
| | |
| | | import com.ruoyi.system.domain.TTestBatteryField; |
| | | import com.ruoyi.system.domain.TTestChannelBinding; |
| | | import com.ruoyi.system.domain.TTestCollectorChannel; |
| | | import com.ruoyi.system.domain.TTestFieldSnapshot; |
| | | import com.ruoyi.system.domain.TTestPlanStep; |
| | | import com.ruoyi.system.domain.TTestResult; |
| | | import com.ruoyi.system.domain.TTestWarningThreshold; |
| | |
| | | TTest selectTestById(Long testId); |
| | | TTest selectTestByIdForUpdate(Long testId); |
| | | List<TTest> selectTestList(TTest test); |
| | | List<TTestBattery> selectBatteryNosByTestIds(@Param("testIds") List<Long> testIds); |
| | | TTest selectTestByName(String testName); |
| | | int insertTest(TTest test); |
| | | int updateTest(TTest test); |
| | | int deleteTestById(@Param("testId") Long testId, @Param("updateBy") String updateBy); |
| | | int deleteTestBindingsByTestId(Long testId); |
| | | int deleteTestCollectorChannelsByTestId(Long testId); |
| | | int deleteTestFieldSnapshotsByTestId(Long testId); |
| | | int deleteTestPlanStepsByTestId(Long testId); |
| | | int deleteTestBatteriesByTestId(Long testId); |
| | | int deleteTestFieldsByTestId(Long testId); |
| | |
| | | int insertTestBatteryField(TTestBatteryField field); |
| | | int insertTestChannelBinding(TTestChannelBinding binding); |
| | | int insertTestCollectorChannel(TTestCollectorChannel mapping); |
| | | int insertTestFieldSnapshot(TTestFieldSnapshot snapshot); |
| | | int insertTestThreshold(TTestWarningThreshold threshold); |
| | | List<TTestPlanStep> selectTestPlanSteps(Long testId); |
| | | List<TTestBattery> selectTestBatteries(Long testId); |
| | | List<TTestBatteryField> selectTestBatteryFields(Long testId); |
| | | List<TTestChannelBinding> selectTestChannelBindings(Long testId); |
| | | List<TTestCollectorChannel> selectTestCollectorChannels(Long testId); |
| | | List<TTestFieldSnapshot> selectTestFieldSnapshots(Long testId); |
| | | List<TTestWarningThreshold> selectTestThresholds(Long testId); |
| | | List<TTestResult> selectTestResults(TTestResult result); |
| | | int countTestTypeEnabled(Long testTypeId); |
| New file |
| | |
| | | package com.ruoyi.system.service; |
| | | |
| | | import java.util.List; |
| | | import com.ruoyi.system.domain.TTestFieldSnapshot; |
| | | |
| | | /** 共享业务字段快照服务,隔离字段来源、快照规则和存储实现。 */ |
| | | public interface ISharedFieldSnapshotService |
| | | { |
| | | /** 从电池组当前共享字段创建一份测试快照。 */ |
| | | List<TTestFieldSnapshot> createForBatteryGroup(Long groupId); |
| | | |
| | | /** 同组编辑保留原快照,切换电池组时按新组创建快照。 */ |
| | | List<TTestFieldSnapshot> resolveForUpdate(Long currentGroupId, Long nextGroupId, |
| | | List<TTestFieldSnapshot> currentSnapshots); |
| | | |
| | | /** 返回测试保存的不可变共享字段快照。 */ |
| | | List<TTestFieldSnapshot> selectByTestId(Long testId); |
| | | |
| | | /** 保存测试的共享字段快照。 */ |
| | | void saveForTest(Long testId, List<TTestFieldSnapshot> snapshots); |
| | | |
| | | /** 删除尚未开始接收的测试快照,以便在同一事务内替换。 */ |
| | | void deleteByTestId(Long testId); |
| | | } |
| New file |
| | |
| | | package com.ruoyi.system.service.impl; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import com.ruoyi.system.domain.TBatteryGroup; |
| | | import com.ruoyi.system.domain.TBatteryGroupRelationField; |
| | | import com.ruoyi.system.domain.TTestFieldSnapshot; |
| | | import com.ruoyi.system.mapper.TSharedFieldSnapshotMapper; |
| | | import com.ruoyi.system.service.ITBatteryGroupService; |
| | | import com.ruoyi.system.service.ISharedFieldSnapshotService; |
| | | |
| | | /** 共享业务字段快照服务实现。 */ |
| | | @Service |
| | | public class TSharedFieldSnapshotServiceImpl implements ISharedFieldSnapshotService |
| | | { |
| | | @Autowired |
| | | private ITBatteryGroupService batteryGroupService; |
| | | |
| | | @Autowired |
| | | private TSharedFieldSnapshotMapper snapshotMapper; |
| | | |
| | | @Override |
| | | public List<TTestFieldSnapshot> createForBatteryGroup(Long groupId) |
| | | { |
| | | TBatteryGroup group = batteryGroupService.selectBatteryGroupById(groupId); |
| | | List<TTestFieldSnapshot> snapshots = new ArrayList<>(); |
| | | for (TBatteryGroupRelationField field : mutable(group.getTemplateFields())) |
| | | { |
| | | snapshots.add(snapshot(field.getBatteryGroupFieldId(), field.getFieldName(), field.getFieldType(), |
| | | field.getFieldValue())); |
| | | } |
| | | return snapshots; |
| | | } |
| | | |
| | | @Override |
| | | public List<TTestFieldSnapshot> resolveForUpdate(Long currentGroupId, Long nextGroupId, |
| | | List<TTestFieldSnapshot> currentSnapshots) |
| | | { |
| | | // 同组编辑不能重新读取活动值,否则会静默改写测试创建时保存的业务事实。 |
| | | if (nextGroupId.equals(currentGroupId)) |
| | | { |
| | | return mutable(currentSnapshots).stream() |
| | | .map(source -> snapshot(source.getFieldDefinitionId(), source.getFieldName(), |
| | | source.getFieldType(), source.getFieldValue())) |
| | | .toList(); |
| | | } |
| | | return createForBatteryGroup(nextGroupId); |
| | | } |
| | | |
| | | @Override |
| | | public List<TTestFieldSnapshot> selectByTestId(Long testId) |
| | | { |
| | | return mutable(snapshotMapper.selectByTestId(testId)); |
| | | } |
| | | |
| | | @Override |
| | | public void saveForTest(Long testId, List<TTestFieldSnapshot> snapshots) |
| | | { |
| | | for (TTestFieldSnapshot snapshot : mutable(snapshots)) |
| | | { |
| | | snapshot.setTestId(testId); |
| | | snapshotMapper.insert(snapshot); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void deleteByTestId(Long testId) |
| | | { |
| | | snapshotMapper.deleteByTestId(testId); |
| | | } |
| | | |
| | | private TTestFieldSnapshot snapshot(Long definitionId, String name, String type, String value) |
| | | { |
| | | TTestFieldSnapshot snapshot = new TTestFieldSnapshot(); |
| | | snapshot.setFieldDefinitionId(definitionId); |
| | | snapshot.setFieldName(name); |
| | | snapshot.setFieldType(type); |
| | | snapshot.setFieldValue(value); |
| | | return snapshot; |
| | | } |
| | | |
| | | private <T> List<T> mutable(List<T> values) |
| | | { |
| | | return values == null ? new ArrayList<>() : new ArrayList<>(values); |
| | | } |
| | | } |
| | |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.system.domain.TTest; |
| | | import com.ruoyi.system.domain.TBatteryGroup; |
| | | import com.ruoyi.system.domain.TBatteryGroupRelationField; |
| | | import com.ruoyi.system.domain.TTestBattery; |
| | | import com.ruoyi.system.domain.TTestBatteryField; |
| | | import com.ruoyi.system.domain.TTestChannelBinding; |
| | | import com.ruoyi.system.domain.TTestCollectorChannel; |
| | | import com.ruoyi.system.domain.TTestFieldSnapshot; |
| | | import com.ruoyi.system.domain.TTestPlanStep; |
| | | import com.ruoyi.system.domain.TTestResult; |
| | | import com.ruoyi.system.domain.TTestWarningThreshold; |
| | | import com.ruoyi.system.domain.vo.TestConfigurationOptionsVo; |
| | | import com.ruoyi.system.mapper.TTestMapper; |
| | | import com.ruoyi.system.service.ITTestService; |
| | | import com.ruoyi.system.service.ITBatteryGroupService; |
| | | import com.ruoyi.system.service.ISharedFieldSnapshotService; |
| | | |
| | | /** 测试配置服务,负责状态边界、关系校验、事务写入和只追加审计。 */ |
| | | @Service |
| | |
| | | private TTestMapper testMapper; |
| | | |
| | | @Autowired |
| | | private ITBatteryGroupService batteryGroupService; |
| | | private ISharedFieldSnapshotService sharedFieldSnapshotService; |
| | | |
| | | @Override |
| | | public TTest selectTestById(Long testId) |
| | |
| | | test.setBatteryNo(trimToNull(test.getBatteryNo())); |
| | | validateQueryStatus(test.getTestStatus(), TEST_STATUSES, "测试状态无效"); |
| | | validateQueryStatus(test.getReceptionStatus(), RECEPTION_STATUSES, "接收状态无效"); |
| | | return testMapper.selectTestList(test); |
| | | List<TTest> tests = mutable(testMapper.selectTestList(test)); |
| | | populateBatteryNos(tests); |
| | | return tests; |
| | | } |
| | | |
| | | @Override |
| | |
| | | validateConfiguration(test); |
| | | test.setTestStatus(WAITING); |
| | | test.setReceptionStatus(NOT_STARTED); |
| | | test.setFieldSnapshots(snapshotGroupFields(test.getBatteries().get(0).getGroupId())); |
| | | test.setFieldSnapshots(sharedFieldSnapshotService.createForBatteryGroup( |
| | | test.getBatteries().get(0).getGroupId())); |
| | | test.setDelFlag("0"); |
| | | test.setCreateTime(new Date()); |
| | | testMapper.insertTest(test); |
| | |
| | | test.setMonitorTimeoutMinutes(current.getMonitorTimeoutMinutes()); |
| | | validateBase(test, true); |
| | | validateConfiguration(test); |
| | | test.setFieldSnapshots(resolveUpdatedFieldSnapshots(test, current)); |
| | | 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("测试配置已变更,请刷新后重试"); |
| | |
| | | testMapper.deleteTestFieldsByTestId(test.getTestId()); |
| | | testMapper.deleteTestBatteriesByTestId(test.getTestId()); |
| | | testMapper.deleteTestThresholdsByTestId(test.getTestId()); |
| | | testMapper.deleteTestFieldSnapshotsByTestId(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)); |
| | |
| | | } |
| | | test.setPlanSteps(planSteps); |
| | | test.setBatteries(batteries); |
| | | test.setBatteryNo(joinBatteryNos(batteries)); |
| | | test.setThresholds(mutable(testMapper.selectTestThresholds(testId))); |
| | | test.setFieldSnapshots(mutable(testMapper.selectTestFieldSnapshots(testId))); |
| | | test.setFieldSnapshots(sharedFieldSnapshotService.selectByTestId(testId)); |
| | | } |
| | | |
| | | private void validateBase(TTest test, boolean update) |
| | |
| | | } |
| | | } |
| | | |
| | | private List<TTestFieldSnapshot> resolveUpdatedFieldSnapshots(TTest test, TTest current) |
| | | private void populateBatteryNos(List<TTest> tests) |
| | | { |
| | | Long nextGroupId = test.getBatteries().get(0).getGroupId(); |
| | | Long currentGroupId = current.getBatteries().isEmpty() ? null : current.getBatteries().get(0).getGroupId(); |
| | | if (nextGroupId.equals(currentGroupId)) |
| | | return mutable(current.getFieldSnapshots()).stream().map(this::copySnapshot).toList(); |
| | | return snapshotGroupFields(nextGroupId); |
| | | if (tests.isEmpty()) return; |
| | | Map<Long, List<TTestBattery>> batteriesByTest = new HashMap<>(); |
| | | List<Long> testIds = tests.stream().map(TTest::getTestId).toList(); |
| | | for (TTestBattery battery : mutable(testMapper.selectBatteryNosByTestIds(testIds))) |
| | | batteriesByTest.computeIfAbsent(battery.getTestId(), ignored -> new ArrayList<>()).add(battery); |
| | | for (TTest item : tests) |
| | | item.setBatteryNo(joinBatteryNos(batteriesByTest.get(item.getTestId()))); |
| | | } |
| | | |
| | | private List<TTestFieldSnapshot> snapshotGroupFields(Long groupId) |
| | | private String joinBatteryNos(List<TTestBattery> batteries) |
| | | { |
| | | TBatteryGroup group = batteryGroupService.selectBatteryGroupById(groupId); |
| | | List<TTestFieldSnapshot> snapshots = new ArrayList<>(); |
| | | for (TBatteryGroupRelationField field : mutable(group.getTemplateFields())) |
| | | { |
| | | TTestFieldSnapshot snapshot = new TTestFieldSnapshot(); |
| | | snapshot.setFieldDefinitionId(field.getBatteryGroupFieldId()); |
| | | snapshot.setFieldName(field.getFieldName()); |
| | | snapshot.setFieldType(field.getFieldType()); |
| | | snapshot.setFieldValue(field.getFieldValue()); |
| | | snapshots.add(snapshot); |
| | | } |
| | | return snapshots; |
| | | } |
| | | |
| | | private TTestFieldSnapshot copySnapshot(TTestFieldSnapshot source) |
| | | { |
| | | TTestFieldSnapshot copy = new TTestFieldSnapshot(); |
| | | copy.setFieldDefinitionId(source.getFieldDefinitionId()); |
| | | copy.setFieldName(source.getFieldName()); |
| | | copy.setFieldType(source.getFieldType()); |
| | | copy.setFieldValue(source.getFieldValue()); |
| | | return copy; |
| | | return mutable(batteries).stream().map(TTestBattery::getBatteryNo).collect(java.util.stream.Collectors.joining("、")); |
| | | } |
| | | |
| | | private void validatePlanSteps(List<TTestPlanStep> planSteps) |
| | |
| | | testMapper.insertTestCollectorChannel(mapping); |
| | | } |
| | | } |
| | | for (TTestFieldSnapshot snapshot : mutable(test.getFieldSnapshots())) |
| | | { |
| | | snapshot.setTestId(test.getTestId()); |
| | | testMapper.insertTestFieldSnapshot(snapshot); |
| | | } |
| | | sharedFieldSnapshotService.saveForTest(test.getTestId(), test.getFieldSnapshots()); |
| | | for (TTestWarningThreshold threshold : test.getThresholds()) |
| | | { |
| | | threshold.setTestId(test.getTestId()); |
| New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8" ?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.ruoyi.system.mapper.TSharedFieldSnapshotMapper"> |
| | | |
| | | <resultMap id="TTestFieldSnapshotResultMap" type="TTestFieldSnapshot"> |
| | | <id property="snapshotId" column="snapshot_id" /> |
| | | <result property="testId" column="test_id" /> |
| | | <result property="fieldDefinitionId" column="field_definition_id" /> |
| | | <result property="fieldName" column="field_name" /> |
| | | <result property="fieldType" column="field_type" /> |
| | | <result property="fieldValue" column="field_value" /> |
| | | </resultMap> |
| | | |
| | | <select id="selectByTestId" parameterType="Long" resultMap="TTestFieldSnapshotResultMap"> |
| | | select snapshot_id, test_id, field_definition_id, field_name, field_type, field_value |
| | | from t_test_field_snapshot where test_id = #{testId} order by snapshot_id |
| | | </select> |
| | | |
| | | <insert id="insert" parameterType="TTestFieldSnapshot" useGeneratedKeys="true" keyProperty="snapshotId"> |
| | | insert into t_test_field_snapshot |
| | | (test_id, field_definition_id, field_name, field_type, field_value) |
| | | values(#{testId}, #{fieldDefinitionId}, #{fieldName}, #{fieldType}, #{fieldValue}) |
| | | </insert> |
| | | |
| | | <delete id="deleteByTestId">delete from t_test_field_snapshot where test_id = #{testId}</delete> |
| | | </mapper> |
| | |
| | | <result property="channelCode" column="channel_code" /> |
| | | </resultMap> |
| | | |
| | | <resultMap id="TTestFieldSnapshotResultMap" type="TTestFieldSnapshot"> |
| | | <id property="snapshotId" column="snapshot_id" /> |
| | | <result property="testId" column="test_id" /> |
| | | <result property="fieldDefinitionId" column="field_definition_id" /> |
| | | <result property="fieldName" column="field_name" /> |
| | | <result property="fieldType" column="field_type" /> |
| | | <result property="fieldValue" column="field_value" /> |
| | | </resultMap> |
| | | |
| | | <resultMap id="TTestPlanStepResultMap" type="TTestPlanStep"> |
| | | <id property="planStepId" column="plan_step_id" /> |
| | | <result property="testId" column="test_id" /> |
| | |
| | | t.test_status, t.reception_status, t.monitor_timeout_minutes, |
| | | t.started_at_utc, t.ended_at_utc, t.del_flag, |
| | | t.create_by, t.create_time, t.update_by, t.update_time, t.remark, |
| | | (select count(1) from t_test_battery b where b.test_id = t.test_id and b.del_flag = 0) battery_count, |
| | | (select group_concat(b.battery_no order by b.relation_id separator '、') |
| | | from t_test_battery b where b.test_id = t.test_id and b.del_flag = 0) battery_no |
| | | (select count(1) from t_test_battery b where b.test_id = t.test_id and b.del_flag = 0) battery_count |
| | | from t_test t |
| | | left join sys_user creator on creator.user_id = t.creator_id and creator.del_flag = '0' |
| | | left join sys_user principal on principal.user_id = t.principal_id and principal.del_flag = '0' |
| | |
| | | <if test="endCreateTime != null">and t.create_time <= #{endCreateTime}</if> |
| | | </where> |
| | | order by t.create_time desc, t.test_id desc |
| | | </select> |
| | | |
| | | <select id="selectBatteryNosByTestIds" resultMap="TTestBatteryResultMap"> |
| | | select test_id, battery_no |
| | | from t_test_battery |
| | | where del_flag = 0 and test_id in |
| | | <foreach collection="testIds" item="testId" open="(" separator="," close=")">#{testId}</foreach> |
| | | order by test_id, relation_id |
| | | </select> |
| | | |
| | | <select id="selectTestById" parameterType="Long" resultMap="TTestResultMap"> |
| | |
| | | |
| | | <delete id="deleteTestBindingsByTestId">delete from t_test_channel_binding where test_id = #{testId}</delete> |
| | | <delete id="deleteTestCollectorChannelsByTestId">delete from t_test_collector_channel where test_id = #{testId}</delete> |
| | | <delete id="deleteTestFieldSnapshotsByTestId">delete from t_test_field_snapshot where test_id = #{testId}</delete> |
| | | <delete id="deleteTestPlanStepsByTestId">delete from t_test_plan_step where test_id = #{testId}</delete> |
| | | <update id="deleteTestFieldsByTestId"> |
| | | update t_test_battery_field f join t_test_battery b on b.relation_id = f.relation_id |
| | |
| | | insert into t_test_collector_channel |
| | | (test_id, battery_relation_id, collector_id, measurement_code, measurement_name, channel_code) |
| | | values(#{testId}, #{batteryRelationId}, #{collectorId}, #{measurementCode}, #{measurementName}, #{channelCode}) |
| | | </insert> |
| | | <insert id="insertTestFieldSnapshot" parameterType="TTestFieldSnapshot" useGeneratedKeys="true" keyProperty="snapshotId"> |
| | | insert into t_test_field_snapshot |
| | | (test_id, field_definition_id, field_name, field_type, field_value) |
| | | values(#{testId}, #{fieldDefinitionId}, #{fieldName}, #{fieldType}, #{fieldValue}) |
| | | </insert> |
| | | <insert id="insertTestThreshold" parameterType="TTestWarningThreshold" useGeneratedKeys="true" keyProperty="thresholdId"> |
| | | insert into t_test_warning_threshold(test_id, metric_code, min_value, max_value, unit, severity, del_flag) |
| | |
| | | measurement_code, measurement_name, channel_code |
| | | from t_test_collector_channel where test_id = #{testId} |
| | | order by battery_relation_id, mapping_id |
| | | </select> |
| | | <select id="selectTestFieldSnapshots" parameterType="Long" resultMap="TTestFieldSnapshotResultMap"> |
| | | select snapshot_id, test_id, field_definition_id, field_name, field_type, field_value |
| | | from t_test_field_snapshot where test_id = #{testId} order by snapshot_id |
| | | </select> |
| | | <select id="selectTestThresholds" parameterType="Long" resultMap="TTestThresholdResultMap"> |
| | | select threshold_id, test_id, metric_code, min_value, max_value, unit, severity, del_flag |