20250325 更新

1.添加 相关的检验数据转换器
2.批量更新检验数据以及计算保留时间相对偏差和离子丰度比
master
陈江保 7 days ago
parent 6f087e2556
commit 262c96c875
  1. 14
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordSampleDataController.java
  2. 51
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/convert/TestRecordSampleDataConverter.java
  3. 14
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/convert/TestSampleDataExpandConverter.java
  4. 58
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SampleInspectDataDTO.java
  5. 56
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordSampleDataDocDTO.java
  6. 3
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordSampleData.java
  7. 9
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordSampleDataMapper.java
  8. 4
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordSampleDataService.java
  9. 7
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordSampledataExpandService.java
  10. 12
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/InspectRecordServiceImpl.java
  11. 72
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordSampleDataServiceImpl.java
  12. 112
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordSampledataExpandServiceImpl.java
  13. 117
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordSampleDataVO.java
  14. 8
      dlp-drugtesting-biz/src/main/resources/mapper/TestRecordSampleDataExpandMapper.xml
  15. 39
      dlp-drugtesting-biz/src/main/resources/mapper/TestRecordSampleDataMapper.xml

@ -30,6 +30,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.security.Principal;
import java.util.Collections;
import java.util.List;
@ -144,15 +145,11 @@ public class TestRecordSampleDataController {
@PutMapping("/updateEntrustTestData")
@ApiOperation(value = "修改导入的实验数据", notes = "修改导入的实验数据")
public R<List<TestRecordSampleData>> updateEntrustTestData(@RequestBody UpdateEntrustTestDataDTO dto) {
public R updateEntrustTestData(@RequestBody @Valid @NotEmpty(message = "参数列表不能为空!") List<SampleInspectDataDTO> dtoList) {
try {
testRecordSampleDataService.validateTestStatus(dto.getTestId());
List<UpdateEntrustTestDataDTO> list = dto.getList();
if (CollUtil.isNotEmpty(list)) {
return R.ok(list.stream().map(testRecordSampleDataService::updateEntrustTestData).collect(Collectors.toList()),"实验数据保存成功");
} else {
return R.ok(Collections.singletonList(testRecordSampleDataService.updateEntrustTestData(dto)));
}
testRecordSampleDataService.validateTestStatus(dtoList.get(0).getTestId());
boolean success = testRecordSampleDataService.updateEntrustTestData(dtoList);
return success ? R.ok("实验数据保存成功") : R.failed("实验数据保存失败");
} catch (Exception e) {
e.printStackTrace();
return R.failed("实验数据保存失败!" + e.getMessage());
@ -287,6 +284,5 @@ public class TestRecordSampleDataController {
return R.ok("更新成功!");
}
}

@ -0,0 +1,51 @@
package digital.laboratory.platform.inspection.convert;
import digital.laboratory.platform.inspection.dto.SampleInspectDataDTO;
import digital.laboratory.platform.inspection.entity.TestRecordSampleData;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author ChenJiangBao
* @version 1.0
* @description: 检验数据转换器
* @date 2025/3/25 17:08
*/
public class TestRecordSampleDataConverter {
/**
* dot entity
* @param dto
* @return
*/
public static TestRecordSampleData dtoToEntity(SampleInspectDataDTO dto) {
if (dto == null) return null;
TestRecordSampleData testRecordSampleData = new TestRecordSampleData();
testRecordSampleData.setId(dto.getId());
testRecordSampleData.setName(dto.getName());
testRecordSampleData.setSampleNo(dto.getSampleNo());
testRecordSampleData.setTestId(dto.getTestId());
testRecordSampleData.setSampleConcentration(dto.getSampleConcentration());
testRecordSampleData.setCompoundName(dto.getCompoundName());
testRecordSampleData.setRtTimeWithinError(dto.getRtTimeWithinError());
testRecordSampleData.setRtTimeError(dto.getRtTimeError());
testRecordSampleData.setTargetRtTime(dto.getTargetRtTime());
testRecordSampleData.setIsDetected(dto.getIsDetected());
testRecordSampleData.setSampleType(dto.getSampleType());
testRecordSampleData.setCompoundCnName(dto.getCompoundCnName());
testRecordSampleData.setWhetherCheckOut(dto.getWhetherCheckOut());
return testRecordSampleData;
}
/**
* dto列表转实体列表
* @param dtoList
* @return
*/
public static List<TestRecordSampleData> dtoToEntityList(List<SampleInspectDataDTO> dtoList) {
if (dtoList == null) return Collections.emptyList();
return dtoList.stream().map(TestRecordSampleDataConverter::dtoToEntity).collect(Collectors.toList());
}
}

@ -3,6 +3,10 @@ package digital.laboratory.platform.inspection.convert;
import digital.laboratory.platform.inspection.dto.TestSampleDataExpandDTO;
import digital.laboratory.platform.inspection.entity.TestRecordSampleDataExpand;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author ChenJiangBao
* @version 1.0
@ -30,4 +34,14 @@ public class TestSampleDataExpandConverter {
return testRecordSampleDataExpand;
}
/**
* dto列表转实体列表
* @param dtoList
* @return
*/
public static List<TestRecordSampleDataExpand> dtoToEntityList(List<TestSampleDataExpandDTO> dtoList) {
if (dtoList == null) return Collections.emptyList();
return dtoList.stream().map(TestSampleDataExpandConverter::dtoToEntity).collect(Collectors.toList());
}
}

@ -0,0 +1,58 @@
package digital.laboratory.platform.inspection.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* 实验中样本检测结果数据 DTO类包含扩展数据
* @TableName b_test_record_sampledata
*/
@Data
@ApiModel(value = "SampleInspectDataDTO", description = "实验中样本检测结果数据 DTO类,包含扩展数据")
public class SampleInspectDataDTO {
@ApiModelProperty(value = "主键标识", example = "123456789")
private String id;
@ApiModelProperty(value = "数据从机器中导出的唯一标识", example = "Sample123")
private String name;
@ApiModelProperty(value = "样本编号", example = "SMP001")
private String sampleNo;
@ApiModelProperty(value = "实验ID", example = "TEST001")
private String testId;
@ApiModelProperty(value = "样品浓度", example = "8.9")
private String sampleConcentration;
@ApiModelProperty(value = "化合物名称", example = "Heroin")
private String compoundName;
@ApiModelProperty(value = "保留时间是否在误差范围内,缴获物(-1~1), 生物样本(-2.5~2.5)", example = "0.5")
private String rtTimeWithinError;
@ApiModelProperty(value = "保留时间相对误差(%)", example = "1.2")
private Double rtTimeError;
@ApiModelProperty(value = "检材保留时间(min)", example = "2.5")
private Double targetRtTime;
@ApiModelProperty(value = "是否检出该物质 1 检出, 0 未检出", example = "1")
private Integer isDetected;
@ApiModelProperty(value = "样本类型 - QC(质控), STD(标准品), Analyte(待测样品)", example = "QC")
private String sampleType;
@ApiModelProperty(value = "检测的化合物的中文名字", example = "海洛因")
private String compoundCnName;
@ApiModelProperty("是否检出, 定性结果")
private String whetherCheckOut;
@ApiModelProperty("样本检验扩展数据列表")
private List<TestSampleDataExpandDTO> expandList;
}

@ -0,0 +1,56 @@
package digital.laboratory.platform.inspection.dto;
import digital.laboratory.platform.inspection.entity.TestRecordSampleData;
import lombok.Data;
@Data
public class TestRecordSampleDataDocDTO extends TestRecordSampleData {
/**
* 离子丰度比 | 峰面积之比
* p 表示打印 (Print)
*/
private String pIonAbundanceRatio;
/**
* 离子丰度比相对偏差%
* 计算公式(目标物离子丰度比 - 标准物离子丰度比) / 标准物质离子丰度比 * 100
* p 表示打印 (Print)
*/
private String pIonAbundanceRatioError;
/**
* 离子丰度比偏差是否在误差范围内
* p 表示打印 (Print)
*/
private String pIonAbundanceRatioWithinError;
/**
* 目标物保留时间
* p 表示打印 (Print)
*/
private String pTargetRtTime;
/**
* 保留时间偏差
* p 表示打印 (Print)
*/
private String pRtTimeError;
/**
* 保留时间偏差是否在误差范围内
* p 表示打印 (Print)
*/
private String pRtTimeWithinError;
/**
* 是否检测到目标物
* p 表示打印 (Print)
*/
private String pIsDetected;
/**
* 样本索引编号
*/
private String indexNum;
}

@ -69,6 +69,9 @@ public class TestRecordSampleData extends BaseEntity {
@ApiModelProperty(value = "检测的化合物的中文名字", example = "海洛因")
private String compoundCnName;
@ApiModelProperty("是否检出, 定性结果")
private String whetherCheckOut;
public TestRecordSampleData() {
}

@ -1,5 +1,6 @@
package digital.laboratory.platform.inspection.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -9,6 +10,7 @@ import digital.laboratory.platform.inspection.dto.DataSolutionSampleDTO;
import digital.laboratory.platform.inspection.dto.TaskTestDataDTO;
import digital.laboratory.platform.inspection.entity.TestRecordSampleData;
import digital.laboratory.platform.inspection.vo.ESTBusinessInfoVO;
import digital.laboratory.platform.inspection.vo.TestRecordSampleDataVO;
import digital.laboratory.platform.inspection.vo.TestResultBusinessVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -25,6 +27,13 @@ import java.util.List;
@Mapper
public interface TestRecordSampleDataMapper extends BaseMapper<TestRecordSampleData> {
/**
* 查询检验数据vo类会携带扩展数据的list属性
* @param wrapper
* @return
*/
List<TestRecordSampleDataVO> queryTestRecordSampleDataVOList(@Param(Constants.WRAPPER) Wrapper<TestRecordSampleData> wrapper);
/**
* 通过业务id查询委托表筛查表任务表
* @param qw

@ -93,10 +93,10 @@ public interface TestRecordSampleDataService extends IService<TestRecordSampleD
/**
* 修改导入的实验数据
*
* @param dto
* @param dtoList
* @return
*/
TestRecordSampleData updateEntrustTestData(UpdateEntrustTestDataDTO dto);
boolean updateEntrustTestData(List<SampleInspectDataDTO> dtoList);
/**
* 获取任务实验结果数据

@ -50,4 +50,11 @@ public interface TestRecordSampledataExpandService extends IService<TestRecordSa
*/
Boolean updateByDTO(TestSampleDataExpandDTO updateDTO);
/**
* 根据DTO去批量更新
*
* @param dtoList
* @return
*/
Boolean updateBatchByDTO(List<TestSampleDataExpandDTO> dtoList);
}

@ -18,7 +18,7 @@ import digital.laboratory.platform.inspection.entity.TestRecordSampleDataExpand;
import digital.laboratory.platform.inspection.enums.BusinessType;
import digital.laboratory.platform.inspection.enums.TestRecordFileUrl;
import digital.laboratory.platform.inspection.service.*;
import digital.laboratory.platform.inspection.vo.TestRecordSampleDataVO;
import digital.laboratory.platform.inspection.dto.TestRecordSampleDataDocDTO;
import digital.laboratory.platform.inspetion.api.entity.EntrustInfo;
import digital.laboratory.platform.inspetion.api.entity.SampleInfo;
import digital.laboratory.platform.inspetion.api.entity.TargetObject;
@ -143,7 +143,7 @@ public class InspectRecordServiceImpl implements InspectRecordService {
Map<String, List<TestRecordSampleData>> dataMap = dataList.stream()
.collect(Collectors.groupingBy(TestRecordSampleData::getCompoundName));
List<TestRecordSampleDataVO> dataDtos = new ArrayList<>();
List<TestRecordSampleDataDocDTO> dataDtos = new ArrayList<>();
// 遍历化合物组
for (Map.Entry<String, List<TestRecordSampleData>> entry : dataMap.entrySet()) {
@ -151,7 +151,7 @@ public class InspectRecordServiceImpl implements InspectRecordService {
List<TestRecordSampleData> list = entry.getValue();
// 添加空白数据
TestRecordSampleDataVO blankVo = new TestRecordSampleDataVO();
TestRecordSampleDataDocDTO blankVo = new TestRecordSampleDataDocDTO();
blankVo.setName("空白" + materialType);
blankVo.setCompoundName(compoundName);
blankVo.setPTargetRtTime("/");
@ -170,7 +170,7 @@ public class InspectRecordServiceImpl implements InspectRecordService {
// 处理标准样品(STD)
if (map.containsKey("STD")) {
TestRecordSampleData std = map.get("STD").get(0);
TestRecordSampleDataVO stdVo = new TestRecordSampleDataVO();
TestRecordSampleDataDocDTO stdVo = new TestRecordSampleDataDocDTO();
BeanUtils.copyProperties(std, stdVo);
List<TestRecordSampleDataExpand> expandList = dataExpandMap.get(std.getId());
if (expandList != null) {
@ -196,10 +196,10 @@ public class InspectRecordServiceImpl implements InspectRecordService {
List<TestRecordSampleData> analyte = map.get("Analyte");
analyte.sort(testRecordSampleDataService.getSortBySampleNo());
List<TestRecordSampleDataVO> dataVOS = new ArrayList<>();
List<TestRecordSampleDataDocDTO> dataVOS = new ArrayList<>();
for (int i = 0; i < analyte.size(); i++) {
TestRecordSampleData item = analyte.get(i);
TestRecordSampleDataVO vo = new TestRecordSampleDataVO();
TestRecordSampleDataDocDTO vo = new TestRecordSampleDataDocDTO();
BeanUtils.copyProperties(item, vo);
vo.setPTargetRtTime(vo.getTargetRtTime().toString());
vo.setPRtTimeError(vo.getRtTimeError().toString());

@ -21,6 +21,7 @@ import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.comservice.entity.DlpDictData;
import digital.laboratory.platform.comservice.feign.RemoteDictDataService;
import digital.laboratory.platform.inspection.convert.TestRecordSampleDataConverter;
import digital.laboratory.platform.inspection.enums.BusinessType;
import digital.laboratory.platform.inspection.enums.StdSolutionNum;
import digital.laboratory.platform.inspection.enums.TaskTestDataStatus;
@ -37,10 +38,7 @@ import digital.laboratory.platform.inspection.service.*;
import digital.laboratory.platform.inspection.utils.datafile.hair.HairSewageCompoundData;
import digital.laboratory.platform.inspection.utils.datafile.nps.NPSDataFileStruct;
import digital.laboratory.platform.inspection.utils.datafile.nps.NPSTestDetailDataStruct;
import digital.laboratory.platform.inspection.vo.ESTBusinessInfoVO;
import digital.laboratory.platform.inspection.vo.ResultConcentrationVO;
import digital.laboratory.platform.inspection.vo.TestRecordReagentVO;
import digital.laboratory.platform.inspection.vo.TestResultBusinessVO;
import digital.laboratory.platform.inspection.vo.*;
import digital.laboratory.platform.inspetion.api.entity.EntrustInfo;
import digital.laboratory.platform.inspetion.api.entity.SampleInfo;
import digital.laboratory.platform.inspetion.api.entity.TestRecord;
@ -246,7 +244,7 @@ public class TestRecordSampleDataServiceImpl extends ServiceImpl<TestRecordSampl
*/
@Override
public List<?> getSampleTestDataByTestId(String testId, String type) {
List<TestRecordSampleData> list = this.list(Wrappers.<TestRecordSampleData>lambdaQuery()
List<TestRecordSampleDataVO> list = baseMapper.queryTestRecordSampleDataVOList(Wrappers.<TestRecordSampleData>lambdaQuery()
.eq(TestRecordSampleData::getTestId, testId)
.last("ORDER BY SUBSTRING_INDEX(name, '-', -1) + 0"));
// List<Object> retList = new ArrayList<>();
@ -419,64 +417,20 @@ public class TestRecordSampleDataServiceImpl extends ServiceImpl<TestRecordSampl
/**
* 修改导入的实验数据
*
* @param dto
* @param dtoList
* @return
*/
@Override
public TestRecordSampleData updateEntrustTestData(UpdateEntrustTestDataDTO dto) {
JSONObject dtoParam = dto.getParam();
TestRecordSampleData oldInfo = this.getById(dtoParam.getString("id")); // 取实验数据id
// 取出老数据,进行更改
JSONObject oldObject = new JSONObject();
if (oldInfo != null) {
oldObject = JSONObject.parseObject(oldInfo.getDataResultJson());
dtoParam.put("testSampleDataList", oldObject.get("testSampleDataList"));
} else {
dtoParam.put("testSampleDataList", new JSONArray());
}
dtoParam.put("businessType", dto.getType());
// 根据类型去判断当前是nps还是毛发
boolean saved = false; // 标记保存是否成功
if (dto.getType().equals(BusinessType.NPS_CASE.getBusinessType())
|| dto.getType().equals(BusinessType.SCREENING_EVENT.getBusinessType())) {
// 设置nps中的testSampleDataList 为空, 因为这里的数据不能修改
/*dtoParam.put("testSampleDataList", null);*/
NPSCaseTestDataDto param = JSONObject.toJavaObject(dtoParam, NPSCaseTestDataDto.class);
return saveOrUpdateTestData(
oldInfo,
param.getCompoundName(),
JSONUtil.toJsonStr(param),
param.getSampleNo(),
param.getTestId(),
param.getSampleName(),
param.getCompoundCnName(),
param.getTargetRtTime(),
param.getRtTimeError(),
param.getTargetConcentration());
} else {
HairSewageDataDto param = JSONObject.toJavaObject(dtoParam, HairSewageDataDto.class);
return saveOrUpdateTestData(
oldInfo,
param.getCompoundName(),
JSONUtil.toJsonStr(param),
param.getSampleNo(),
param.getTestId(),
param.getSampleName(),
param.getCompoundCnName(),
param.getTargetRtTime(),
param.getRtTimeError(),
param.getTargetConcentration());
public boolean updateEntrustTestData(List<SampleInspectDataDTO> dtoList) {
List<TestRecordSampleData> testRecordSampleDataList = TestRecordSampleDataConverter.dtoToEntityList(dtoList);
if (super.updateBatchById(testRecordSampleDataList)) {
// 开启异步执行
CompletableFuture.runAsync(() -> {
testRecordSampleDataList.forEach(item -> calculateInspectData(item.getId()));
});
return testRecordSampledataExpandService.updateBatchByDTO(dtoList.stream().flatMap(dto -> dto.getExpandList().stream()).collect(Collectors.toList()));
}
// // 根据成功标识返回
// if (saved) {
// // 保存成功, 返回成功的json对象
// return dtoParam;
// } else {
// // 保存失败, 返回之前的json对象
// return oldObject;
// }
return false;
}
/**

@ -28,16 +28,18 @@ import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
/**
* @author ChenJiangBao
* @description 针对表b_test_record_sampledata_expand(样本检验数据的扩展信息)的数据库操作Service实现
* @createDate 2025-03-19 14:58:17
*/
* @author ChenJiangBao
* @description 针对表b_test_record_sampledata_expand(样本检验数据的扩展信息)的数据库操作Service实现
* @createDate 2025-03-19 14:58:17
*/
@Service
public class TestRecordSampledataExpandServiceImpl extends ServiceImpl<TestRecordSampleDataExpandMapper, TestRecordSampleDataExpand>
implements TestRecordSampledataExpandService{
implements TestRecordSampledataExpandService {
@Resource
private TestRecordService testRecordService;
@ -50,6 +52,7 @@ public class TestRecordSampledataExpandServiceImpl extends ServiceImpl<TestRecor
/**
* 封装处理毛发案件任务等检验扩展数据信息
*
* @param hairSewageDataDto
* @param testDataId
* @return
@ -103,8 +106,9 @@ public class TestRecordSampledataExpandServiceImpl extends ServiceImpl<TestRecor
/**
* 根据业务类型保存检验数据扩展信息
* @param testDataId 检验数据id
* @param drug 对应的标准品毒品清单
*
* @param testDataId 检验数据id
* @param drug 对应的标准品毒品清单
* @param businessType 业务类型
* @return
*/
@ -145,7 +149,8 @@ public class TestRecordSampledataExpandServiceImpl extends ServiceImpl<TestRecor
}
/**
*根据DTO去更新
* 根据DTO去更新
*
* @param updateDTO
* @return
*/
@ -170,23 +175,7 @@ public class TestRecordSampledataExpandServiceImpl extends ServiceImpl<TestRecor
stdDataExpandList = super.list(Wrappers.<TestRecordSampleDataExpand>lambdaQuery().eq(TestRecordSampleDataExpand::getTestDataId, stdTestSampleData.getId()));
}
if (sampleDataExpand.getPeakArea() != null && basePeakData.getPeakArea() != null) {
sampleDataExpand.setIonAbundanceRatio(sampleDataExpand.getPeakArea().divide(basePeakData.getPeakArea(), 5, BigDecimal.ROUND_HALF_UP));
if (CollUtil.isNotEmpty(stdDataExpandList)) {
stdDataExpandList.forEach(stdDataExpand -> {
if (stdDataExpand.getMassToChargeRatio().equals(sampleDataExpand.getMassToChargeRatio())) {
BigDecimal ionAbundanceRatioError = sampleDataExpand.getIonAbundanceRatio()
.subtract(stdDataExpand.getIonAbundanceRatio())
.divide(stdDataExpand.getIonAbundanceRatio(), 5, BigDecimal.ROUND_HALF_UP)
.multiply(BigDecimal.valueOf(100));
sampleDataExpand.setIonAbundanceRatioError(ionAbundanceRatioError);
if (testRecord.getBusinessType().equals(BusinessType.NPS_CASE.getBusinessType())) {
sampleDataExpand.setIonAbundanceRatioWithinError(processInspectDataService.getWithinErrorText(ionAbundanceRatioError, processInspectDataService.getErrorRange(sampleDataExpand.getIonAbundanceRatio())));
} else {
sampleDataExpand.setIonAbundanceRatioWithinError(processInspectDataService.calculateHairCaseIonAbundanceRatioWithinError(ionAbundanceRatioError.doubleValue(), stdDataExpand.getIonAbundanceRatio().doubleValue()));
}
}
});
}
calculateIonAbundanceRatio(basePeakData, testRecord, stdDataExpandList, sampleDataExpand);
update = super.updateById(sampleDataExpand);
}
@ -195,6 +184,79 @@ public class TestRecordSampledataExpandServiceImpl extends ServiceImpl<TestRecor
return update;
}
/**
* 根据DTO去批量更新
*
* @param dtoList
* @return
*/
@Override
public Boolean updateBatchByDTO(List<TestSampleDataExpandDTO> dtoList) {
List<TestRecordSampleDataExpand> expandList = TestSampleDataExpandConverter.dtoToEntityList(dtoList);
if (super.updateBatchById(expandList)) {
CompletableFuture.runAsync(() -> {
List<TestRecordSampleDataExpand> newExpandDatList = super.listByIds(expandList.stream().map(TestRecordSampleDataExpand::getId).collect(Collectors.toList()));
Map<String, List<TestRecordSampleDataExpand>> expandDataGroupByDataId = newExpandDatList.stream().collect(Collectors.groupingBy(TestRecordSampleDataExpand::getTestDataId));
List<TestRecordSampleDataExpand> calculateAfterResult = new ArrayList<>();
expandDataGroupByDataId.forEach((key, value) -> {
// 查询对应的基峰数据是否存在
TestRecordSampleDataExpand basePeakData = value.stream().filter(TestRecordSampleDataExpand::getBasePeak).findFirst().orElse(null);
if (basePeakData != null) {
// 获取标准物质的扩展信息,1 先查询对应的实验数据 2 根据实验数据的实验id以及化合物以及类型获取标准物质的实验数据信息 3 根据标准物质实验数据id取对应的扩展数据
TestRecordSampleData testRecordSampleData = testRecordSampleDataService.getById(key);
TestRecord testRecord = testRecordService.getById(testRecordSampleData.getTestId());
List<TestRecordSampleDataExpand> stdDataExpandList = null;
if (!testRecordSampleData.getSampleType().equals(TestRecordSampleDataConstant.SAMPLE_TYPE_STD)) {
TestRecordSampleData stdTestSampleData = testRecordSampleDataService.getOne(Wrappers.<TestRecordSampleData>lambdaQuery().eq(TestRecordSampleData::getTestId, testRecordSampleData.getTestId()).eq(TestRecordSampleData::getCompoundName, testRecordSampleData.getCompoundName()).eq(TestRecordSampleData::getSampleType, TestRecordSampleDataConstant.SAMPLE_TYPE_STD));
stdDataExpandList = super.list(Wrappers.<TestRecordSampleDataExpand>lambdaQuery().eq(TestRecordSampleDataExpand::getTestDataId, stdTestSampleData.getId()));
}
List<TestRecordSampleDataExpand> finalStdDataExpandList = stdDataExpandList;
value.forEach(sampleDataExpand -> {
calculateIonAbundanceRatio(basePeakData, testRecord, finalStdDataExpandList, sampleDataExpand);
calculateAfterResult.add(sampleDataExpand);
});
}
});
if (CollUtil.isNotEmpty(calculateAfterResult)) {
super.updateBatchById(calculateAfterResult);
}
});
return Boolean.TRUE;
}
return Boolean.FALSE;
}
/**
* 计算离子丰度比
*
* @param basePeakData 基准峰数据
* @param testRecord 测试记录
* @param finalStdDataExpandList 最终标准数据扩展列表
* @param sampleDataExpand 样本数据扩展
*/
private void calculateIonAbundanceRatio(TestRecordSampleDataExpand basePeakData, TestRecord testRecord, List<TestRecordSampleDataExpand> finalStdDataExpandList, TestRecordSampleDataExpand sampleDataExpand) {
if (sampleDataExpand.getPeakArea() != null && basePeakData.getPeakArea() != null) {
sampleDataExpand.setIonAbundanceRatio(sampleDataExpand.getPeakArea().divide(basePeakData.getPeakArea(), 5, BigDecimal.ROUND_HALF_UP));
if (CollUtil.isNotEmpty(finalStdDataExpandList)) {
finalStdDataExpandList.forEach(stdDataExpand -> {
if (stdDataExpand.getMassToChargeRatio().equals(sampleDataExpand.getMassToChargeRatio())) {
BigDecimal ionAbundanceRatioError = sampleDataExpand.getIonAbundanceRatio()
.subtract(stdDataExpand.getIonAbundanceRatio())
.divide(stdDataExpand.getIonAbundanceRatio(), 5, BigDecimal.ROUND_HALF_UP)
.multiply(BigDecimal.valueOf(100));
sampleDataExpand.setIonAbundanceRatioError(ionAbundanceRatioError);
if (testRecord.getBusinessType().equals(BusinessType.NPS_CASE.getBusinessType())) {
sampleDataExpand.setIonAbundanceRatioWithinError(processInspectDataService.getWithinErrorText(ionAbundanceRatioError, processInspectDataService.getErrorRange(sampleDataExpand.getIonAbundanceRatio())));
} else {
sampleDataExpand.setIonAbundanceRatioWithinError(processInspectDataService.calculateHairCaseIonAbundanceRatioWithinError(ionAbundanceRatioError.doubleValue(), stdDataExpand.getIonAbundanceRatio().doubleValue()));
}
}
});
}
}
}
/**
* 根据提供的参数创建一个TestRecordSampleDataExpand对象

@ -1,57 +1,74 @@
package digital.laboratory.platform.inspection.vo;
import digital.laboratory.platform.inspection.entity.TestRecordSampleData;
import digital.laboratory.platform.inspection.entity.TestRecordSampleDataExpand;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
* 样本检验数据 VO类
* @TableName b_test_record_sampledata
*/
@Data
public class TestRecordSampleDataVO extends TestRecordSampleData {
/**
* 离子丰度比 | 峰面积之比
* p 表示打印 (Print)
*/
private String pIonAbundanceRatio;
/**
* 离子丰度比相对偏差%
* 计算公式(目标物离子丰度比 - 标准物离子丰度比) / 标准物质离子丰度比 * 100
* p 表示打印 (Print)
*/
private String pIonAbundanceRatioError;
/**
* 离子丰度比偏差是否在误差范围内
* p 表示打印 (Print)
*/
private String pIonAbundanceRatioWithinError;
/**
* 目标物保留时间
* p 表示打印 (Print)
*/
private String pTargetRtTime;
/**
* 保留时间偏差
* p 表示打印 (Print)
*/
private String pRtTimeError;
/**
* 保留时间偏差是否在误差范围内
* p 表示打印 (Print)
*/
private String pRtTimeWithinError;
/**
* 是否检测到目标物
* p 表示打印 (Print)
*/
private String pIsDetected;
/**
* 样本索引编号
*/
private String indexNum;
@ApiModel(value = "TestRecordSampleDataVO", description = "实验中样本检测结果数据 VO类")
public class TestRecordSampleDataVO {
@ApiModelProperty(value = "主键标识", example = "123456789")
private String id;
@ApiModelProperty(value = "数据从机器中导出的唯一标识", example = "Sample123")
private String name;
@ApiModelProperty(value = "样本编号", example = "SMP001")
private String sampleNo;
@ApiModelProperty(value = "实验ID", example = "TEST001")
private String testId;
@ApiModelProperty(value = "标准品浓度", example = "10.5")
private String stdConcentration;
@ApiModelProperty(value = "样品浓度", example = "8.9")
private String sampleConcentration;
@ApiModelProperty(value = "化合物名称", example = "Heroin")
private String compoundName;
@ApiModelProperty(value = "保留时间是否在误差范围内,缴获物(-1~1), 生物样本(-2.5~2.5)", example = "0.5")
private String rtTimeWithinError;
@ApiModelProperty(value = "保留时间相对误差(%)", example = "1.2")
private Double rtTimeError;
@ApiModelProperty(value = "检材保留时间(min)", example = "2.5")
private Double targetRtTime;
@ApiModelProperty(value = "标准品保留时间(min)", example = "2.6")
private Double stdRtTime;
@ApiModelProperty(value = "是否检出该物质 1 检出, 0 未检出", example = "1")
private Integer isDetected;
@ApiModelProperty(value = "样本类型 - QC(质控), STD(标准品), Analyte(待测样品)", example = "QC")
private String sampleType;
@ApiModelProperty(value = "检验数据 JSON", example = "{\"mass\": 146, \"intensity\": 200}")
private String dataJson;
@ApiModelProperty(value = "检验结果数据 JSON", example = "{\"result\": \"Positive\"}")
private String dataResultJson;
@ApiModelProperty(value = "状态:0-待审核, 1-已审核, 2-已审批, 3-已上传", example = "1")
private Integer status;
@ApiModelProperty(value = "检测的化合物的中文名字", example = "海洛因")
private String compoundCnName;
@ApiModelProperty("是否检出, 定性结果")
private String whetherCheckOut;
@ApiModelProperty("样本检验扩展数据列表")
private List<TestRecordSampleDataExpand> expandList;
}

@ -28,7 +28,7 @@
exp.base_peak,
exp.ion_abundance_ratio,
exp.ion_abundance_ratio_error,
exp.fragment_ret_time
exp.fragment_ret_time,
exp.ion_abundance_ratio_within_error,
exp.mass_to_charge_ratio,
exp.qualitative_ion_pair,
@ -45,4 +45,10 @@
LEFT JOIN b_test_record_sampledata test ON exp.test_data_id = test.id
</sql>
<select id="queryExpandDataByTestDataId" resultType="digital.laboratory.platform.inspection.entity.TestRecordSampleDataExpand">
SELECT
<include refid="Base_Column_List"></include>
FROM b_test_record_sampledata_expand exp WHERE exp.test_data_id = #{testDataId}
</select>
</mapper>

@ -25,6 +25,34 @@
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
<result property="updateBy" column="update_by" jdbcType="VARCHAR"/>
<result property="compoundCnName" column="compound_cn_name" jdbcType="VARCHAR"/>
<result property="whetherCheckOut" column="whether_check_out" jdbcType="VARCHAR"/>
</resultMap>
<resultMap id="VOMap" type="digital.laboratory.platform.inspection.vo.TestRecordSampleDataVO">
<id property="id" column="id" jdbcType="VARCHAR"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
<result property="sampleNo" column="sample_no" jdbcType="VARCHAR"/>
<result property="testId" column="test_id" jdbcType="VARCHAR"/>
<result property="stdConcentration" column="std_concentration" jdbcType="VARCHAR"/>
<result property="sampleConcentration" column="sample_concentration" jdbcType="VARCHAR"/>
<result property="compoundName" column="compound_name" jdbcType="VARCHAR"/>
<result property="rtTimeWithinError" column="rt_time_within_error" jdbcType="VARCHAR"/>
<result property="rtTimeError" column="rt_time_error" jdbcType="DOUBLE"/>
<result property="targetRtTime" column="target_rt_time" jdbcType="DOUBLE"/>
<result property="stdRtTime" column="std_rt_time" jdbcType="DOUBLE"/>
<result property="isDetected" column="is_detected" jdbcType="INTEGER"/>
<result property="sampleType" column="sample_type" jdbcType="VARCHAR"/>
<result property="dataJson" column="data_json" jdbcType="VARCHAR"/>
<result property="dataResultJson" column="data_result_json" jdbcType="VARCHAR"/>
<result property="status" column="status" jdbcType="TINYINT"/>
<result property="compoundCnName" column="compound_cn_name" jdbcType="VARCHAR"/>
<result property="whetherCheckOut" column="whether_check_out" jdbcType="VARCHAR"/>
<collection
property="expandList"
ofType="digital.laboratory.platform.inspection.entity.TestRecordSampleDataExpand"
javaType="java.util.List"
column="id"
select="digital.laboratory.platform.inspection.mapper.TestRecordSampleDataExpandMapper.queryExpandDataByTestDataId" />
</resultMap>
<sql id="Base_Column_List">
@ -48,8 +76,17 @@
create_by,
update_time,
update_by,
compound_cn_name
compound_cn_name,
whether_check_out
</sql>
<select id="queryTestRecordSampleDataVOList" resultMap="VOMap">
SELECT
<include refid="Base_Column_List"></include>
FROM b_test_record_sampledata
${ew.customSqlSegment}
</select>
<!-- 合并委托、任务、筛查表-->
<sql id="queryCommoneBusinessSql">
SELECT T.id,

Loading…
Cancel
Save