20250325 更新
1.添加 相关的检验数据转换器 2.批量更新检验数据以及计算保留时间相对偏差和离子丰度比
This commit is contained in:
@@ -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());
|
||||
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()));
|
||||
}
|
||||
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());
|
||||
}
|
||||
// // 根据成功标识返回
|
||||
// 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;
|
||||
@ApiModel(value = "TestRecordSampleDataVO", description = "实验中样本检测结果数据 VO类")
|
||||
public class TestRecordSampleDataVO {
|
||||
|
||||
/**
|
||||
* 离子丰度比相对偏差(%)
|
||||
* 计算公式:(目标物离子丰度比 - 标准物离子丰度比) / 标准物质离子丰度比 * 100
|
||||
* p 表示打印 (Print)
|
||||
*/
|
||||
private String pIonAbundanceRatioError;
|
||||
@ApiModelProperty(value = "主键标识", example = "123456789")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 离子丰度比偏差是否在误差范围内
|
||||
* p 表示打印 (Print)
|
||||
*/
|
||||
private String pIonAbundanceRatioWithinError;
|
||||
@ApiModelProperty(value = "数据从机器中导出的唯一标识", example = "Sample123")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 目标物保留时间
|
||||
* p 表示打印 (Print)
|
||||
*/
|
||||
private String pTargetRtTime;
|
||||
@ApiModelProperty(value = "样本编号", example = "SMP001")
|
||||
private String sampleNo;
|
||||
|
||||
/**
|
||||
* 保留时间偏差
|
||||
* p 表示打印 (Print)
|
||||
*/
|
||||
private String pRtTimeError;
|
||||
@ApiModelProperty(value = "实验ID", example = "TEST001")
|
||||
private String testId;
|
||||
|
||||
/**
|
||||
* 保留时间偏差是否在误差范围内
|
||||
* p 表示打印 (Print)
|
||||
*/
|
||||
private String pRtTimeWithinError;
|
||||
@ApiModelProperty(value = "标准品浓度", example = "10.5")
|
||||
private String stdConcentration;
|
||||
|
||||
/**
|
||||
* 是否检测到目标物
|
||||
* p 表示打印 (Print)
|
||||
*/
|
||||
private String pIsDetected;
|
||||
@ApiModelProperty(value = "样品浓度", example = "8.9")
|
||||
private String sampleConcentration;
|
||||
|
||||
/**
|
||||
* 样本索引编号
|
||||
*/
|
||||
private String indexNum;
|
||||
@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,
|
||||
|
||||
Reference in New Issue
Block a user