package com.ruoyi.system.service.impl;
|
|
import java.math.BigDecimal;
|
import java.util.Date;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Set;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.system.domain.TTest;
|
import com.ruoyi.system.domain.TTestBattery;
|
import com.ruoyi.system.domain.TTestBatteryField;
|
import com.ruoyi.system.domain.TTestResult;
|
import com.ruoyi.system.domain.TTestWarningThreshold;
|
import com.ruoyi.system.mapper.TTestMapper;
|
import com.ruoyi.system.service.ITTestService;
|
|
/**
|
* 测试管理事务服务。
|
* 负责测试资源校验、状态机和聚合关系写入,避免检测过程中修改资源配置。
|
*/
|
@Service
|
public class TTestServiceImpl implements ITTestService
|
{
|
private static final String WAITING = "0";
|
private static final String TESTING = "1";
|
private static final String ABNORMAL = "2";
|
private static final String FINISHED = "3";
|
|
@Autowired
|
private TTestMapper testMapper;
|
|
@Override
|
public TTest selectTestById(Long testId)
|
{
|
if (testId == null) throw new ServiceException("测试ID不能为空");
|
TTest test = testMapper.selectTestById(testId);
|
if (test == null) throw new ServiceException("测试不存在");
|
List<TTestBattery> batteries = testMapper.selectTestBatteries(testId);
|
List<TTestBatteryField> fields = testMapper.selectTestBatteryFields(testId);
|
for (TTestBattery battery : batteries)
|
{
|
battery.setFields(fields.stream().filter(field -> battery.getRelationId().equals(field.getRelationId())).toList());
|
}
|
test.setBatteries(batteries);
|
test.setThresholds(testMapper.selectTestThresholds(testId));
|
return test;
|
}
|
|
@Override
|
public List<TTest> selectTestList(TTest test)
|
{
|
if (test == null) test = new TTest();
|
test.setTestName(trimToNull(test.getTestName()));
|
test.setBatteryNo(trimToNull(test.getBatteryNo()));
|
validateStatus(test.getStatus());
|
return testMapper.selectTestList(test);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public int insertTest(TTest test)
|
{
|
validateBase(test, false);
|
validateRelations(test);
|
test.setStatus(WAITING);
|
test.setDelFlag("0");
|
test.setCreateTime(new Date());
|
testMapper.insertTest(test);
|
saveRelations(test);
|
return 1;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public int updateTest(TTest test)
|
{
|
validateBase(test, true);
|
TTest current = selectTestById(test.getTestId());
|
if (!WAITING.equals(current.getStatus())) throw new ServiceException("仅待检测状态允许编辑草稿");
|
validateRelations(test);
|
test.setUpdateTime(new Date());
|
int rows = testMapper.updateTest(test);
|
testMapper.deleteTestFieldsByTestId(test.getTestId(), test.getUpdateBy());
|
testMapper.deleteTestBatteriesByTestId(test.getTestId(), test.getUpdateBy());
|
testMapper.deleteTestThresholdsByTestId(test.getTestId(), test.getUpdateBy());
|
saveRelations(test);
|
return rows;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public int startTest(Long testId, String updateBy)
|
{
|
TTest current = selectTestById(testId);
|
if (!WAITING.equals(current.getStatus())) throw new ServiceException("只有待检测状态可以启动");
|
validateRelations(current);
|
return testMapper.updateTestStatus(testId, TESTING, updateBy);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public int deleteTestByIds(Long[] testIds, String updateBy)
|
{
|
if (testIds == null || testIds.length == 0) throw new ServiceException("请选择要删除的测试");
|
for (Long testId : testIds)
|
{
|
TTest test = selectTestById(testId);
|
if (TESTING.equals(test.getStatus()) || ABNORMAL.equals(test.getStatus()))
|
throw new ServiceException("检测中或异常测试不能删除");
|
}
|
int rows = 0;
|
for (Long testId : testIds) rows += testMapper.deleteTestById(testId, updateBy);
|
return rows;
|
}
|
|
@Override
|
public List<TTestResult> selectTestResults(TTestResult result)
|
{
|
if (result == null || result.getTestId() == null) throw new ServiceException("测试ID不能为空");
|
selectTestById(result.getTestId());
|
return testMapper.selectTestResults(result);
|
}
|
|
private void validateBase(TTest test, boolean update)
|
{
|
if (test == null) throw new ServiceException("测试信息不能为空");
|
test.setTestName(trimToNull(test.getTestName()));
|
test.setTestPurpose(trimToNull(test.getTestPurpose()));
|
test.setRemark(trimToNull(test.getRemark()));
|
if (StringUtils.isEmpty(test.getTestName())) throw new ServiceException("测试名称不能为空");
|
if (test.getTestName().length() > 100) throw new ServiceException("测试名称长度不能超过100个字符");
|
if (StringUtils.isEmpty(test.getTestPurpose())) throw new ServiceException("测试目的不能为空");
|
if (test.getRemark() != null && test.getRemark().length() > 500) throw new ServiceException("备注长度不能超过500个字符");
|
if (test.getPrincipalId() == null || testMapper.countUserEnabled(test.getPrincipalId()) == 0) throw new ServiceException("负责人不存在或已停用");
|
if (test.getTestTypeId() == null || testMapper.countTestTypeEnabled(test.getTestTypeId()) == 0) throw new ServiceException("测试类型不存在或未启用");
|
TTest same = testMapper.selectTestByName(test.getTestName());
|
if (same != null && (!update || !test.getTestId().equals(same.getTestId()))) throw new ServiceException("测试名称已存在");
|
}
|
|
private void validateRelations(TTest test)
|
{
|
if (test.getBatteries() == null || test.getBatteries().isEmpty()) throw new ServiceException("至少配置一个测试电池");
|
if (test.getThresholds() == null || test.getThresholds().isEmpty()) throw new ServiceException("至少配置一个预警阈值");
|
Set<String> batteryNos = new HashSet<>();
|
Set<String> resources = new HashSet<>();
|
for (TTestBattery battery : test.getBatteries())
|
{
|
if (battery == null || battery.getGroupId() == null || StringUtils.isEmpty(trimToNull(battery.getBatteryNo()))
|
|| battery.getCabinetId() == null || battery.getCollectorId() == null) throw new ServiceException("测试电池关系资料不完整");
|
battery.setBatteryNo(trimToNull(battery.getBatteryNo()));
|
validateChannel(battery.getTestChannelNo(), "测试通道");
|
validateChannel(battery.getTemperatureChannelNo(), "温度通道");
|
validateChannel(battery.getPositiveChannelNo(), "正电位通道");
|
validateChannel(battery.getNegativeChannelNo(), "负电位通道");
|
if (battery.getTemperatureChannelNo().equals(battery.getPositiveChannelNo())
|
|| battery.getTemperatureChannelNo().equals(battery.getNegativeChannelNo())
|
|| battery.getPositiveChannelNo().equals(battery.getNegativeChannelNo())) throw new ServiceException("温度及正负电位通道不能重复");
|
if (!batteryNos.add(battery.getBatteryNo())) throw new ServiceException("测试电池号不能重复");
|
String resource = battery.getCabinetId() + ":" + battery.getTestChannelNo();
|
if (!resources.add(resource)) throw new ServiceException("检测柜测试通道不能重复");
|
if (testMapper.countBatteryInEnabledGroup(battery.getGroupId(), battery.getBatteryNo()) == 0)
|
throw new ServiceException("电池号不属于指定的启用电池组");
|
if (testMapper.countCabinetEnabled(battery.getCabinetId()) == 0)
|
throw new ServiceException("检测柜不存在或未启用");
|
if (testMapper.countCollectorEnabled(battery.getCollectorId(), battery.getCabinetId()) == 0)
|
throw new ServiceException("采集器不存在、未启用或不属于指定检测柜");
|
if (testMapper.countTestingByBatteryNo(battery.getBatteryNo(), test.getTestId()) > 0
|
|| testMapper.countTestingByCabinetChannel(battery.getCabinetId(), battery.getTestChannelNo(), test.getTestId()) > 0)
|
throw new ServiceException("电池号或检测柜测试通道已被检测中的任务占用");
|
if (battery.getFields() == null || battery.getFields().isEmpty()) throw new ServiceException("每个测试电池必须配置扩展属性");
|
Set<String> fieldNames = new HashSet<>();
|
for (TTestBatteryField field : battery.getFields())
|
if (field == null || StringUtils.isEmpty(trimToNull(field.getFieldName())) || !fieldNames.add(field.getFieldName().trim())) throw new ServiceException("扩展属性名称不能为空且不能重复");
|
}
|
Set<String> thresholdTypes = new HashSet<>();
|
for (TTestWarningThreshold threshold : test.getThresholds())
|
{
|
if (threshold == null || StringUtils.isEmpty(trimToNull(threshold.getThresholdType())) || threshold.getMinValue() == null || threshold.getMaxValue() == null) throw new ServiceException("阈值配置不完整");
|
threshold.setThresholdType(threshold.getThresholdType().trim());
|
if (!thresholdTypes.add(threshold.getThresholdType())) throw new ServiceException("阈值类型不能重复");
|
if (threshold.getMinValue().compareTo(threshold.getMaxValue()) > 0) throw new ServiceException("阈值最小值不能大于最大值");
|
if (!threshold.getThresholdType().contains(":")) throw new ServiceException("阈值类型必须包含通道号");
|
}
|
}
|
|
private void saveRelations(TTest test)
|
{
|
for (TTestBattery battery : test.getBatteries())
|
{
|
battery.setTestId(test.getTestId());
|
testMapper.insertTestBattery(battery);
|
for (TTestBatteryField field : battery.getFields())
|
{
|
field.setRelationId(battery.getRelationId());
|
testMapper.insertTestBatteryField(field);
|
}
|
}
|
for (TTestWarningThreshold threshold : test.getThresholds())
|
{
|
threshold.setTestId(test.getTestId());
|
testMapper.insertTestThreshold(threshold);
|
}
|
}
|
|
private void validateChannel(Integer channel, String name)
|
{
|
if (channel == null || channel < 0) throw new ServiceException(name + "必须为非负整数");
|
}
|
|
private void validateStatus(String status)
|
{
|
if (StringUtils.isNotEmpty(status) && !WAITING.equals(status) && !TESTING.equals(status) && !ABNORMAL.equals(status) && !FINISHED.equals(status)) throw new ServiceException("测试状态无效");
|
}
|
|
private String trimToNull(String value)
|
{
|
String trimmed = StringUtils.trim(value);
|
return StringUtils.isEmpty(trimmed) ? null : trimmed;
|
}
|
}
|