| | |
| | | package com.ruoyi.system.service.impl; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONException; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | import com.ruoyi.system.domain.TTest; |
| | | import com.ruoyi.system.domain.TTestBattery; |
| | | import com.ruoyi.system.domain.TTestBatteryField; |
| | | import com.ruoyi.system.domain.TTestChannelBinding; |
| | | 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; |
| | | |
| | | /** |
| | | * 测试管理事务服务。 |
| | | * 负责测试资源校验、状态机和聚合关系写入,避免检测过程中修改资源配置。 |
| | | */ |
| | | /** 测试配置服务,负责状态边界、关系校验、事务写入和只追加审计。 */ |
| | | @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"; |
| | | private static final String WAITING = "WAITING"; |
| | | private static final String NOT_MONITORED = "NOT_MONITORED"; |
| | | private static final Set<String> TEST_STATUSES = Set.of( |
| | | WAITING, "RUNNING", "PAUSED", "RUNNING_ABNORMAL", "COMPLETION_PENDING", "COMPLETED", "TERMINATED"); |
| | | private static final Set<String> MONITORING_STATUSES = Set.of( |
| | | NOT_MONITORED, "WAITING_DEVICE_START", "MONITORING", "BACKFILLING", "MONITORING_ENDED", "CANCELLED"); |
| | | private static final Set<String> THRESHOLD_UNITS = Set.of("A", "V", "Ah", "Wh", "℃"); |
| | | |
| | | @Autowired |
| | | private TTestMapper testMapper; |
| | |
| | | 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)); |
| | | loadConfiguration(test); |
| | | return test; |
| | | } |
| | | |
| | |
| | | if (test == null) test = new TTest(); |
| | | test.setTestName(trimToNull(test.getTestName())); |
| | | test.setBatteryNo(trimToNull(test.getBatteryNo())); |
| | | validateStatus(test.getStatus()); |
| | | validateQueryStatus(test.getTestStatus(), TEST_STATUSES, "测试状态无效"); |
| | | validateQueryStatus(test.getMonitoringStatus(), MONITORING_STATUSES, "监测状态无效"); |
| | | return testMapper.selectTestList(test); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int insertTest(TTest test) |
| | | public TestConfigurationOptionsVo selectConfigurationOptions() |
| | | { |
| | | TestConfigurationOptionsVo options = new TestConfigurationOptionsVo(); |
| | | options.setUsers(testMapper.selectEnabledUserOptions()); |
| | | options.setTestTypes(testMapper.selectEnabledTestTypeOptions()); |
| | | options.setBatteries(testMapper.selectEnabledBatteryOptions()); |
| | | options.setChannels(testMapper.selectRegisteredChannelOptions()); |
| | | options.setCollectors(testMapper.selectEnabledCollectorOptions()); |
| | | return options; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createTest(TTest test) |
| | | { |
| | | if (test == null) throw new ServiceException("测试信息不能为空"); |
| | | test.setCreatorId(test.getOperatorId()); |
| | | if (test.getMonitorTimeoutMinutes() == null) test.setMonitorTimeoutMinutes(30); |
| | | validateBase(test, false); |
| | | validateRelations(test); |
| | | test.setStatus(WAITING); |
| | | validateConfiguration(test); |
| | | test.setTestStatus(WAITING); |
| | | test.setMonitoringStatus(NOT_MONITORED); |
| | | test.setDelFlag("0"); |
| | | test.setCreateTime(new Date()); |
| | | testMapper.insertTest(test); |
| | | saveRelations(test); |
| | | return 1; |
| | | saveConfiguration(test); |
| | | testMapper.insertTestAudit(test.getTestId(), "TEST_CREATED", test.getOperatorId(), test.getCreateBy(), |
| | | null, JSON.toJSONString(test)); |
| | | return test.getTestId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int updateTest(TTest test) |
| | | { |
| | | if (test == null || test.getTestId() == null) throw new ServiceException("测试ID不能为空"); |
| | | TTest current = testMapper.selectTestByIdForUpdate(test.getTestId()); |
| | | if (current == null) throw new ServiceException("测试不存在"); |
| | | loadConfiguration(current); |
| | | if (!NOT_MONITORED.equals(current.getMonitoringStatus())) |
| | | throw new ServiceException("开始监测后不能修改测试配置"); |
| | | |
| | | test.setCreatorId(current.getCreatorId()); |
| | | test.setTestStatus(current.getTestStatus()); |
| | | test.setMonitoringStatus(current.getMonitoringStatus()); |
| | | if (test.getMonitorTimeoutMinutes() == null) |
| | | test.setMonitorTimeoutMinutes(current.getMonitorTimeoutMinutes()); |
| | | validateBase(test, true); |
| | | TTest current = selectTestById(test.getTestId()); |
| | | if (!WAITING.equals(current.getStatus())) throw new ServiceException("仅待检测状态允许编辑草稿"); |
| | | validateRelations(test); |
| | | validateConfiguration(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); |
| | | if (rows != 1) throw new ServiceException("测试配置已变更,请刷新后重试"); |
| | | |
| | | // 监测开始前没有原始采集事实,配置关系可在同一事务内整体替换,审计记录仍只追加。 |
| | | testMapper.deleteTestBindingsByTestId(test.getTestId()); |
| | | testMapper.deleteTestPlanStepsByTestId(test.getTestId()); |
| | | testMapper.deleteTestFieldsByTestId(test.getTestId()); |
| | | testMapper.deleteTestBatteriesByTestId(test.getTestId()); |
| | | testMapper.deleteTestThresholdsByTestId(test.getTestId()); |
| | | saveConfiguration(test); |
| | | testMapper.insertTestAudit(test.getTestId(), "TEST_CONFIGURATION_UPDATED", test.getOperatorId(), |
| | | test.getUpdateBy(), JSON.toJSONString(current), JSON.toJSONString(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); |
| | | throw new ServiceException("开始监测由后续监测动作处理"); |
| | | } |
| | | |
| | | @Override |
| | |
| | | public int deleteTestByIds(Long[] testIds, String updateBy) |
| | | { |
| | | if (testIds == null || testIds.length == 0) throw new ServiceException("请选择要删除的测试"); |
| | | int rows = 0; |
| | | for (Long testId : testIds) |
| | | { |
| | | TTest test = selectTestById(testId); |
| | | if (TESTING.equals(test.getStatus()) || ABNORMAL.equals(test.getStatus())) |
| | | throw new ServiceException("检测中或异常测试不能删除"); |
| | | TTest current = testMapper.selectTestByIdForUpdate(testId); |
| | | if (current == null) throw new ServiceException("测试不存在"); |
| | | if (!NOT_MONITORED.equals(current.getMonitoringStatus())) throw new ServiceException("开始监测后不能删除测试"); |
| | | rows += testMapper.deleteTestById(testId, updateBy); |
| | | } |
| | | int rows = 0; |
| | | for (Long testId : testIds) rows += testMapper.deleteTestById(testId, updateBy); |
| | | return rows; |
| | | } |
| | | |
| | |
| | | return testMapper.selectTestResults(result); |
| | | } |
| | | |
| | | private void loadConfiguration(TTest test) |
| | | { |
| | | Long testId = test.getTestId(); |
| | | List<TTestPlanStep> planSteps = mutable(testMapper.selectTestPlanSteps(testId)); |
| | | for (TTestPlanStep step : planSteps) |
| | | { |
| | | try |
| | | { |
| | | step.setParameters(JSON.parseObject(step.getParametersJson())); |
| | | } |
| | | catch (JSONException exception) |
| | | { |
| | | throw new ServiceException("计划工步参数无法解析"); |
| | | } |
| | | } |
| | | |
| | | List<TTestBattery> batteries = mutable(testMapper.selectTestBatteries(testId)); |
| | | List<TTestBatteryField> fields = mutable(testMapper.selectTestBatteryFields(testId)); |
| | | Map<Long, TTestChannelBinding> bindings = new HashMap<>(); |
| | | for (TTestChannelBinding binding : mutable(testMapper.selectTestChannelBindings(testId))) |
| | | bindings.put(binding.getBatteryRelationId(), binding); |
| | | for (TTestBattery battery : batteries) |
| | | { |
| | | battery.setBinding(bindings.get(battery.getRelationId())); |
| | | battery.setFields(fields.stream() |
| | | .filter(field -> battery.getRelationId().equals(field.getRelationId())) |
| | | .toList()); |
| | | } |
| | | test.setPlanSteps(planSteps); |
| | | test.setBatteries(batteries); |
| | | test.setThresholds(mutable(testMapper.selectTestThresholds(testId))); |
| | | } |
| | | |
| | | 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 (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("测试类型不存在或未启用"); |
| | | if (test.getMonitorTimeoutMinutes() == null || test.getMonitorTimeoutMinutes() < 1 |
| | | || test.getMonitorTimeoutMinutes() > 1440) |
| | | throw new ServiceException("监测超时分钟数必须在1到1440之间"); |
| | | if (test.getCreatorId() == null || testMapper.countUserEnabled(test.getCreatorId()) == 0) |
| | | throw new ServiceException("创建人不存在或已停用"); |
| | | 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("测试名称已存在"); |
| | | if (same != null && (!update || !test.getTestId().equals(same.getTestId()))) |
| | | throw new ServiceException("测试名称已存在"); |
| | | } |
| | | |
| | | private void validateRelations(TTest test) |
| | | private void validateConfiguration(TTest test) |
| | | { |
| | | if (test.getBatteries() == null || test.getBatteries().isEmpty()) throw new ServiceException("至少配置一个测试电池"); |
| | | if (test.getThresholds() == null || test.getThresholds().isEmpty()) throw new ServiceException("至少配置一个预警阈值"); |
| | | validateBatteries(test.getBatteries()); |
| | | validatePlanSteps(test.getPlanSteps()); |
| | | validateThresholds(test.getThresholds()); |
| | | } |
| | | |
| | | private void validateBatteries(List<TTestBattery> batteries) |
| | | { |
| | | if (batteries == null || batteries.isEmpty()) throw new ServiceException("测试至少绑定一个电池号"); |
| | | Set<String> batteryNos = new HashSet<>(); |
| | | Set<String> resources = new HashSet<>(); |
| | | for (TTestBattery battery : test.getBatteries()) |
| | | Set<Long> channelIds = new HashSet<>(); |
| | | Long groupId = null; |
| | | for (TTestBattery battery : batteries) |
| | | { |
| | | if (battery == null || battery.getGroupId() == null || StringUtils.isEmpty(trimToNull(battery.getBatteryNo())) |
| | | || battery.getCabinetId() == null || battery.getCollectorId() == null) throw new ServiceException("测试电池关系资料不完整"); |
| | | if (battery == null || battery.getGroupId() == null) throw new ServiceException("电池组不能为空"); |
| | | if (groupId == null) groupId = battery.getGroupId(); |
| | | else if (!groupId.equals(battery.getGroupId())) 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 (battery.getBatteryNo() == null) throw new ServiceException("电池号不能为空"); |
| | | if (!batteryNos.add(battery.getBatteryNo())) 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("阈值类型必须包含通道号"); |
| | | throw new ServiceException("电池号不属于所选启用电池组"); |
| | | |
| | | TTestChannelBinding binding = battery.getBinding(); |
| | | if (binding == null || binding.getChannelId() == null) throw new ServiceException("主要检测柜通道不能为空"); |
| | | if (!channelIds.add(binding.getChannelId())) throw new ServiceException("同一检测柜通道不可重复绑定"); |
| | | if (testMapper.countRegisteredChannel(binding.getChannelId()) == 0) |
| | | throw new ServiceException("检测柜通道不存在、未登记或未启用"); |
| | | binding.setExpectedBarcode(trimToNull(binding.getExpectedBarcode())); |
| | | if (binding.getExpectedBarcode() != null && binding.getExpectedBarcode().length() > 100) |
| | | throw new ServiceException("预期条码长度不能超过100个字符"); |
| | | if (battery.getCollectorId() != null && testMapper.countCollectorEnabled(battery.getCollectorId()) == 0) |
| | | throw new ServiceException("采集器不存在或未启用"); |
| | | validateBatteryFields(battery.getFields()); |
| | | } |
| | | } |
| | | |
| | | private void saveRelations(TTest test) |
| | | private void validateBatteryFields(List<TTestBatteryField> fields) |
| | | { |
| | | if (fields == null) return; |
| | | Set<String> fieldNames = new HashSet<>(); |
| | | for (TTestBatteryField field : fields) |
| | | { |
| | | if (field == null) throw new ServiceException("扩展属性不能为空"); |
| | | field.setFieldName(trimToNull(field.getFieldName())); |
| | | if (field.getFieldName() == null || !fieldNames.add(field.getFieldName())) |
| | | throw new ServiceException("扩展属性名称不能为空且不可重复"); |
| | | } |
| | | } |
| | | |
| | | private void validatePlanSteps(List<TTestPlanStep> planSteps) |
| | | { |
| | | if (planSteps == null || planSteps.isEmpty()) throw new ServiceException("计划工步不能为空"); |
| | | Set<String> identities = new HashSet<>(); |
| | | Set<Integer> orders = new HashSet<>(); |
| | | for (TTestPlanStep step : planSteps) |
| | | { |
| | | if (step == null || step.getCycleNo() == null || step.getCycleNo() < 1 |
| | | || step.getStepNo() == null || step.getStepNo() < 1 |
| | | || step.getSortOrder() == null || step.getSortOrder() < 1) |
| | | throw new ServiceException("计划工步序号必须为正整数"); |
| | | step.setStepType(trimToNull(step.getStepType())); |
| | | step.setStepName(trimToNull(step.getStepName())); |
| | | if (step.getStepType() == null || step.getStepName() == null || step.getParameters() == null) |
| | | throw new ServiceException("计划工步配置不完整"); |
| | | if (!identities.add(step.getCycleNo() + ":" + step.getStepNo()) || !orders.add(step.getSortOrder())) |
| | | throw new ServiceException("计划工步序号不可重复"); |
| | | step.setParametersJson(JSON.toJSONString(step.getParameters())); |
| | | } |
| | | } |
| | | |
| | | private void validateThresholds(List<TTestWarningThreshold> thresholds) |
| | | { |
| | | if (thresholds == null || thresholds.isEmpty()) throw new ServiceException("阈值配置不能为空"); |
| | | Set<String> metricCodes = new HashSet<>(); |
| | | for (TTestWarningThreshold threshold : thresholds) |
| | | { |
| | | if (threshold == null) throw new ServiceException("阈值配置不完整"); |
| | | threshold.setMetricCode(trimToNull(threshold.getMetricCode())); |
| | | threshold.setUnit(trimToNull(threshold.getUnit())); |
| | | threshold.setSeverity(trimToNull(threshold.getSeverity())); |
| | | if (threshold.getMetricCode() == null || !metricCodes.add(threshold.getMetricCode())) |
| | | throw new ServiceException("阈值指标编码不能为空且不可重复"); |
| | | if (threshold.getMinValue() == null && threshold.getMaxValue() == null) |
| | | throw new ServiceException("阈值最小值和最大值至少填写一项"); |
| | | if (threshold.getMinValue() != null && threshold.getMaxValue() != null |
| | | && threshold.getMinValue().compareTo(threshold.getMaxValue()) > 0) |
| | | throw new ServiceException("阈值最小值不能大于最大值"); |
| | | if (!THRESHOLD_UNITS.contains(threshold.getUnit())) throw new ServiceException("阈值单位无效"); |
| | | if (threshold.getSeverity() == null) threshold.setSeverity("WARNING"); |
| | | } |
| | | } |
| | | |
| | | 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); |
| | | for (TTestBatteryField field : battery.getFields()) |
| | | if (battery.getFields() != null) |
| | | { |
| | | field.setRelationId(battery.getRelationId()); |
| | | testMapper.insertTestBatteryField(field); |
| | | for (TTestBatteryField field : battery.getFields()) |
| | | { |
| | | field.setRelationId(battery.getRelationId()); |
| | | testMapper.insertTestBatteryField(field); |
| | | } |
| | | } |
| | | TTestChannelBinding binding = battery.getBinding(); |
| | | binding.setTestId(test.getTestId()); |
| | | binding.setBatteryRelationId(battery.getRelationId()); |
| | | binding.setClaimStatus("PENDING"); |
| | | testMapper.insertTestChannelBinding(binding); |
| | | } |
| | | for (TTestWarningThreshold threshold : test.getThresholds()) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | private void validateChannel(Integer channel, String name) |
| | | private void validateQueryStatus(String status, Set<String> allowed, String message) |
| | | { |
| | | 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("测试状态无效"); |
| | | if (StringUtils.isNotEmpty(status) && !allowed.contains(status)) throw new ServiceException(message); |
| | | } |
| | | |
| | | private String trimToNull(String value) |
| | |
| | | String trimmed = StringUtils.trim(value); |
| | | return StringUtils.isEmpty(trimmed) ? null : trimmed; |
| | | } |
| | | |
| | | private <T> List<T> mutable(List<T> values) |
| | | { |
| | | return values == null ? new ArrayList<>() : new ArrayList<>(values); |
| | | } |
| | | } |