yeg
2026-09-03 e35881f24e349e865d7a1dbbebc1a7e55ecc7a16
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTestServiceImpl.java
@@ -26,6 +26,7 @@
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.TDetectionChannel;
import com.ruoyi.system.domain.vo.TestConfigurationOptionsVo;
import com.ruoyi.system.mapper.TTestMapper;
@@ -330,6 +331,57 @@
        return rows;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveConsoleDetail(Long testId, TTestConsoleDetail detail, Long operatorId, String updateBy)
    {
        if (testId == null || operatorId == null || detail == null) throw new ServiceException("测试详情不能为空");
        TTest current = testMapper.selectTestByIdForUpdate(testId);
        if (current == null) throw new ServiceException("测试不存在");
        String experimentName = trimToNull(detail.getExperimentName());
        if (experimentName != null && experimentName.length() > 200) throw new ServiceException("实验名称长度不能超过200个字符");
        detail.setExperimentName(experimentName);
        validateConsoleFields(detail.getBatteryFields());
        validateConsoleFields(detail.getSpecialFields());
        validateConsoleValues(testId, detail);
        int rows = testMapper.updateConsoleDetail(testId, JSON.toJSONString(detail), updateBy, new Date());
        if (rows != 1) throw new ServiceException("测试详情保存失败,请刷新后重试");
        return rows;
    }
    private void validateConsoleFields(List<String> fields)
    {
        if (fields == null) return;
        Set<String> names = new HashSet<>();
        for (String field : fields)
        {
            String normalized = trimToNull(field);
            if (normalized == null || normalized.length() > 100 || !names.add(normalized))
                throw new ServiceException("测试详情字段不能为空、长度不能超过100且不可重复");
        }
    }
    private void validateConsoleValues(Long testId, TTestConsoleDetail detail)
    {
        Set<String> allowedFields = new HashSet<>();
        if (detail.getBatteryFields() != null) allowedFields.addAll(detail.getBatteryFields());
        if (detail.getSpecialFields() != null) allowedFields.addAll(detail.getSpecialFields());
        Set<String> batteryNos = new HashSet<>();
        List<TTestBattery> batteries = testMapper.selectTestBatteries(testId);
        if (batteries != null) for (TTestBattery battery : batteries) batteryNos.add(battery.getBatteryNo());
        if (detail.getFieldValues() == null) return;
        for (Map.Entry<String, Map<String, String>> entry : detail.getFieldValues().entrySet())
        {
            if (!allowedFields.contains(entry.getKey()) || entry.getValue() == null)
                throw new ServiceException("测试详情字段值结构无效");
            for (Map.Entry<String, String> value : entry.getValue().entrySet())
            {
                if (!batteryNos.contains(value.getKey()) || (value.getValue() != null && value.getValue().length() > 500))
                    throw new ServiceException("测试详情电池号或字段值无效");
            }
        }
    }
    private void loadConfiguration(TTest test)
    {
        Long testId = test.getTestId();
@@ -384,6 +436,10 @@
        try { test.setLogicStepMappings(mappingJson == null || mappingJson.isBlank()
                ? new ArrayList<>() : JSON.parseArray(mappingJson, TTestLogicStepMapping.class)); }
        catch (JSONException exception) { throw new ServiceException("逻辑工步设置无法解析"); }
        String detailJson = test.getConsoleDetailJson();
        try { test.setConsoleDetail(detailJson == null || detailJson.isBlank()
                ? null : JSON.parseObject(detailJson, TTestConsoleDetail.class)); }
        catch (JSONException exception) { throw new ServiceException("测试详情无法解析"); }
    }
    private void validateBase(TTest test, boolean update)