Merge remote-tracking branch 'origin/master'

# Conflicts:
#	dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/InspectRecordServiceImpl.java
master
陈江保 5 days ago
commit ba460ea36c
  1. 2
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordController.java
  2. 22
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordSampleData.java
  3. 2
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/InspectRecordService.java
  4. 3
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordSampleDataService.java
  5. 338
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/InspectRecordServiceImpl.java
  6. 16
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordSampleDataServiceImpl.java
  7. 17
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordServiceImpl.java
  8. 25
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordSampleDataVO.java

@ -223,7 +223,7 @@ public class TestRecordController {
@ApiOperation("生成检验记录-贵阳禁毒")
@GetMapping("/inspectionRecord")
public R inspectionRecord(String entrustId, String materialType) throws Exception {
return inspectRecordService.inspectionRecord(entrustId, materialType);
return inspectRecordService.buildInspectionRecord(entrustId, materialType);
}
}

@ -106,4 +106,26 @@ public class TestRecordSampleData extends BaseEntity {
*/
private String compoundCnName;
public TestRecordSampleData() {
}
public TestRecordSampleData(String id, String name, String sampleNo, String testId, String stdConcentration, String sampleConcentration, String compoundName, String rtTimeWithinError, Double rtTimeError, Double targetRtTime, Double stdRtTime, Integer isDetected, String sampleType, String dataJson, String dataResultJson, Integer status, String compoundCnName) {
this.id = id;
this.name = name;
this.sampleNo = sampleNo;
this.testId = testId;
this.stdConcentration = stdConcentration;
this.sampleConcentration = sampleConcentration;
this.compoundName = compoundName;
this.rtTimeWithinError = rtTimeWithinError;
this.rtTimeError = rtTimeError;
this.targetRtTime = targetRtTime;
this.stdRtTime = stdRtTime;
this.isDetected = isDetected;
this.sampleType = sampleType;
this.dataJson = dataJson;
this.dataResultJson = dataResultJson;
this.status = status;
this.compoundCnName = compoundCnName;
}
}

@ -16,5 +16,5 @@ public interface InspectRecordService {
* @return
* @throws Exception
*/
R inspectionRecord(String entrustId, String materialType) throws Exception;
R buildInspectionRecord(String entrustId, String materialType) throws Exception;
}

@ -15,6 +15,7 @@ import digital.laboratory.platform.inspection.utils.datafile.nps.NPSDataFileStru
import digital.laboratory.platform.inspection.vo.TestResultBusinessVO;
import javax.servlet.http.HttpServletRequest;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
@ -168,6 +169,8 @@ public interface TestRecordSampleDataService extends IService<TestRecordSampleD
*/
void delete(String testId);
Comparator getSortBySampleNo();
//获取标准品样品信息数据
// List<NPSCaseTestDataDto> getStdSampleTestDataByTestId(String testId);

@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
@ -12,24 +11,27 @@ import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.inspection.enums.BusinessType;
import digital.laboratory.platform.inspection.enums.TestRecordFileUrl;
import digital.laboratory.platform.inspection.dto.HairSewageDataDto;
import digital.laboratory.platform.inspection.dto.NPSCaseTestDataDto;
import digital.laboratory.platform.inspection.constant.BusinessType;
import digital.laboratory.platform.inspection.constant.TestRecordFileUrl;
import digital.laboratory.platform.inspection.entity.TestRecordInstrument;
import digital.laboratory.platform.inspection.entity.TestRecordReagent;
import digital.laboratory.platform.inspection.entity.TestRecordSampleData;
import digital.laboratory.platform.inspection.entity.TestRecordSampleDataExpand;
import digital.laboratory.platform.inspection.service.*;
import digital.laboratory.platform.inspection.vo.TestRecordSampleDataVO;
import digital.laboratory.platform.inspetion.api.entity.EntrustInfo;
import digital.laboratory.platform.inspetion.api.entity.SampleInfo;
import digital.laboratory.platform.inspetion.api.entity.TargetObject;
import digital.laboratory.platform.inspetion.api.entity.TestRecord;
import digital.laboratory.platform.sys.enums.entrust.EntrustBiologyType;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -62,45 +64,51 @@ public class InspectRecordServiceImpl implements InspectRecordService {
@Resource
private SampleInfoService sampleInfoService;
@Resource
private TestRecordSampledataExpandService testRecordSampledataExpandService;
/**
* 生成检验记录-贵阳禁毒
*
* @param entrustId 委托id
* @param entrustId 委托id
* @param materialType 标注当前委托的检材是尿液还是毛发
* @return
* @throws Exception
*/
@Override
public R inspectionRecord(String entrustId, String materialType) throws Exception {
public R buildInspectionRecord(String entrustId, String materialType) throws Exception {
EntrustInfo entrustInfo = entrustInfoService.getById(entrustId);
if (entrustInfo == null) {
return R.ok(false, "委托信息不存在!");
}
String type = entrustInfo.getBusinessType();
if (type.equals(BusinessType.BOINT_CASE.getBusinessType())) {
// Map<String, Object> map = this.invivoRecord(entrustInfo);
return R.ok(this.createInVivoFile(entrustInfo, materialType), "生成成功!");
if (entrustInfo.getBusinessType().equals(BusinessType.BOINT_CASE.getBusinessType())) {
return R.ok(this.buildInVivoDocFile(entrustInfo, materialType), "生成成功!");
}
return R.ok(this.generateCommonDrugInpectRecord(entrustId));
}
/**
* 生成生物样本检验记录数据map
* @param entrustInfo 委托实体信息
*
* @param entrustInfo 委托实体信息
* @param materialType 检材类型
* @return
* @throws Exception
*/
public Map<String, Object> invivoRecord(EntrustInfo entrustInfo, String materialType) throws Exception {
public Map<String, Object> buildInVivoRecordData(EntrustInfo entrustInfo, String materialType) throws Exception {
// 获取检验记录信息
TestRecord testRecord = testRecordService.getTestRecordByBusinessId(entrustInfo.getId());
if (testRecord == null) {
throw new Exception("未找到检验记录信息");
}
// 生成基础数据
HashMap<String, Object> data = buildCommonInspectRecordDocMap(entrustInfo, testRecord, materialType);
// 获取仪器设备数据
// 获取仪器设备数据(批量查询,减少数据库压力)
List<String> deviceIdList = testRecord.getDeviceIdList();
List<TestRecordInstrument> instruments = CollectionUtils.isEmpty(deviceIdList)
? Collections.emptyList()
@ -109,84 +117,119 @@ public class InspectRecordServiceImpl implements InspectRecordService {
data.put("instrumentName", CollectionUtils.isEmpty(instruments)
? "未找到仪器设备数据!"
: instruments.stream()
.map(TestRecordInstrument::getInstrumentName)
.collect(Collectors.joining("\n"))
);
: instruments.stream().map(TestRecordInstrument::getInstrumentName)
.collect(Collectors.joining("\n")));
// 获取样品检测数据
List<HairSewageDataDto> hairDataDtos = (List<HairSewageDataDto>) testRecordSampleDataService
.getSampleTestDataByBusiness(entrustInfo.getId());
// 获取样品数据
List<TestRecordSampleData> dataList = testRecordSampleDataService.list(
Wrappers.<TestRecordSampleData>lambdaQuery().eq(TestRecordSampleData::getTestId, testRecord.getId()));
if (CollectionUtils.isEmpty(hairDataDtos)) {
if (CollectionUtils.isEmpty(dataList)) {
data.put("dataDtos", Collections.emptyList());
data.put("sampleSize", 0);
data.put("vo", testRecord);
return data;
}
// 处理检测数据
Map<String, List<HairSewageDataDto>> dataMap = hairDataDtos.stream()
.collect(Collectors.groupingBy(HairSewageDataDto::getCompoundName));
// 批量查询所有样品扩展数据,避免多次查询数据库
Map<String, List<TestRecordSampleDataExpand>> dataExpandMap = testRecordSampledataExpandService.list(
Wrappers.<TestRecordSampleDataExpand>lambdaQuery()
.in(TestRecordSampleDataExpand::getTestDataId, dataList.stream().map(TestRecordSampleData::getId).collect(Collectors.toList()))
).stream().collect(Collectors.groupingBy(TestRecordSampleDataExpand::getTestDataId));
// 根据化合物名称分组
Map<String, List<TestRecordSampleData>> dataMap = dataList.stream()
.collect(Collectors.groupingBy(TestRecordSampleData::getCompoundName));
List<HairSewageDataDto> dataDtos = new ArrayList<>();
List<TestRecordSampleDataVO> dataDtos = new ArrayList<>();
// 遍历化合物组
for (Map.Entry<String, List<TestRecordSampleData>> entry : dataMap.entrySet()) {
String compoundName = entry.getKey();
List<TestRecordSampleData> list = entry.getValue();
dataMap.forEach((compoundName, list) -> {
// 添加空白数据
HairSewageDataDto blankDto = new HairSewageDataDto();
blankDto.setSampleName("空白");
blankDto.setCompoundName(compoundName);
blankDto.setTmpTargetRtTime("/");
blankDto.setTmpRtTimeError("/");
blankDto.setRtTimeWithinError("否");
blankDto.setTmpIonAbundanceRatio("/");
blankDto.setWhetherCheckOut("否");
dataDtos.add(blankDto);
// 处理样品数据
list.removeIf(item -> {
if (StringUtils.equals(item.getSampleType(), "STD")) {
item.setSampleName("空白添加");
item.setWhetherCheckOut("是");
dataDtos.add(item);
return true;
} else if (StringUtils.equals(item.getSampleType(), "QC")) {
return true;
TestRecordSampleDataVO blankVo = new TestRecordSampleDataVO();
blankVo.setName("空白");
blankVo.setCompoundName(compoundName);
dataDtos.add(blankVo);
// 根据样品类型分组
Map<String, List<TestRecordSampleData>> map = list.stream()
.collect(Collectors.groupingBy(TestRecordSampleData::getSampleType));
// 处理标准样品(STD)
if (map.containsKey("STD")) {
TestRecordSampleData std = map.get("STD").get(0);
TestRecordSampleDataVO stdVo = new TestRecordSampleDataVO();
BeanUtils.copyProperties(std, stdVo);
stdVo.setName("空白添加");
stdVo.setIsDetected(1);
List<TestRecordSampleDataExpand> expandList = dataExpandMap.get(std.getId());
if (expandList != null) {
for (TestRecordSampleDataExpand expand : expandList) {
if (!expand.getBasePeak()) {
stdVo.setIonAbundanceRatio(expand.getIonAbundanceRatio());
stdVo.setIonAbundanceRatioError(expand.getIonAbundanceRatioError());
stdVo.setIonAbundanceRatioWithinError(expand.getIonAbundanceRatioWithinError());
break; // 只取第一个符合条件的扩展数据
}
}
}
return false;
});
dataDtos.add(stdVo);
}
// 排序
list.sort(this.getSortBySampleNo("inVivo"));
// 处理检材样品(Analyte)
if (map.containsKey("Analyte")) {
List<TestRecordSampleData> analyte = map.get("Analyte");
analyte.sort(testRecordSampleDataService.getSortBySampleNo());
List<TestRecordSampleDataVO> dataVOS = new ArrayList<>();
for (int i = 0; i < analyte.size(); i++) {
TestRecordSampleData item = analyte.get(i);
TestRecordSampleDataVO vo = new TestRecordSampleDataVO();
BeanUtils.copyProperties(item, vo);
List<TestRecordSampleDataExpand> expandList = dataExpandMap.get(item.getId());
if (expandList != null) {
for (TestRecordSampleDataExpand expand : expandList) {
if (!expand.getBasePeak()) {
vo.setIonAbundanceRatio(expand.getIonAbundanceRatio());
vo.setIonAbundanceRatioError(expand.getIonAbundanceRatioError());
vo.setIonAbundanceRatioWithinError(expand.getIonAbundanceRatioWithinError());
break; // 只取第一个符合条件的扩展数据
}
}
}
// 重新命名样品
if (list.size() == 1) {
list.get(0).setSampleName("检材样品");
} else {
for (int i = 0; i < list.size(); i++) {
list.get(i).setSampleName((i + 1) + "号检材样品");
// 重新命名样品
vo.setName((analyte.size() == 1) ? "检材样品" : (i + 1) + "号检材样品");
dataVOS.add(vo);
}
dataDtos.addAll(dataVOS);
}
}
dataDtos.addAll(list);
});
// 返回处理后的数据
data.put("dataDtos", dataDtos);
data.put("sampleSize", dataDtos.size());
data.put("inspectOpinion", this.buildInspectOpinion(dataList));
return data;
}
/**
* 根据委托信息和样本类型生成生物样本检验记录文件
*
* @param entrustInfo 委托信息对象
* @param entrustInfo 委托信息对象
* @param materialType 样本类型"毛发""尿液"
* @return 生成的生物样本检验记录文件的路径
* @throws Exception 如果文件生成过程中出现错误抛出异常
*/
public String createInVivoFile(EntrustInfo entrustInfo, String materialType) throws Exception {
public String buildInVivoDocFile(EntrustInfo entrustInfo, String materialType) throws Exception {
// 获取文件数据map
Map<String, Object> data = this.invivoRecord(entrustInfo, materialType);
Map<String, Object> data = this.buildInVivoRecordData(entrustInfo, materialType);
// 调用模板生成检验记录
String templatePath = "";
if (materialType.equals("毛发")) {
@ -203,10 +246,10 @@ public class InspectRecordServiceImpl implements InspectRecordService {
/**
* 根据委托信息模板路径配置和数据构建文档文件并上传到OSS
*
* @param entrustId 委托id
* @param entrustId 委托id
* @param templatePath 模板文件路径
* @param config 配置信息
* @param data 要填充到模板中的数据
* @param config 配置信息
* @param data 要填充到模板中的数据
* @return 上传后的文件路径
* @throws Exception 可能抛出的异常
*/
@ -238,44 +281,6 @@ public class InspectRecordServiceImpl implements InspectRecordService {
return path;
}
public Comparator getSortBySampleNo(String type) {
if (type.equals("inVivo")) {
Comparator<HairSewageDataDto> comparator = Comparator.comparing(
HairSewageDataDto::getSampleNo,
(a, b) -> {
String[] partsA = a.split("-");
String[] partsB = b.split("-");
// 逐部分比较数值
for (int i = 0; i < 3; i++) {
int numA = Integer.parseInt(partsA[i]);
int numB = Integer.parseInt(partsB[i]);
if (numA != numB) return Integer.compare(numA, numB);
}
return 0; // 所有部分相同
}
);
return comparator;
} else {
Comparator<NPSCaseTestDataDto> comparator = Comparator.comparing(
NPSCaseTestDataDto::getSampleNo,
(a, b) -> {
String[] partsA = a.split("-");
String[] partsB = b.split("-");
// 逐部分比较数值
for (int i = 0; i < 3; i++) {
int numA = Integer.parseInt(partsA[i]);
int numB = Integer.parseInt(partsB[i]);
if (numA != numB) return Integer.compare(numA, numB);
}
return 0; // 所有部分相同
}
);
return comparator;
}
}
/**
* 生成常规毒品的检验记录贵阳禁毒
@ -330,6 +335,8 @@ public class InspectRecordServiceImpl implements InspectRecordService {
data.put("inspectMonth", testRecord.getTestStartDate().getMonthValue());
data.put("inspectDay", testRecord.getTestStartDate().getDayOfMonth());
data.put("acceptNo", entrustInfo.getAcceptNo());
// 检材性状描述和检验要求成分
List<SampleInfo> sampleInfoList = getSampleInfosByMaterialType(entrustInfo, materialType);
String materialCharacterDesc = buildMaterialCharacterDesc(sampleInfoList);
@ -384,7 +391,7 @@ public class InspectRecordServiceImpl implements InspectRecordService {
/**
* 根据委托信息和检材类型获取检材信息列表
*
* @param entrustInfo 委托信息对象
* @param entrustInfo 委托信息对象
* @param materialType 检材类型, 毛发或尿液
* @return 检材信息列表
*/
@ -449,4 +456,127 @@ public class InspectRecordServiceImpl implements InspectRecordService {
return String.join(";", descriptions) + "。"; // 用分号连接不同类型的描述
}
public String buildInspectOpinion(List<TestRecordSampleData> dataList) {
// 1. 检查输入的dataList是否为空,如果为空直接返回当前数据。
if (dataList == null || dataList.isEmpty()) {
return "";
}
// 2. 初始化数据结构,用于分类和记录检出与未检出的物质
// - detectedMap 用来存储检出物质的样本信息,key为样本编号,value为检出的物质列表
// - notDetectedMap 用来存储未检出物质的样本信息,key为样本编号,value为未检出的物质列表
// - allCompoundNames 用来存储所有物质名称的集合,方便后续处理
Map<String, List<String>> detectedMap = new LinkedHashMap<>();
Map<String, List<String>> notDetectedMap = new LinkedHashMap<>();
Set<String> allCompoundNames = new HashSet<>();
// 3. 遍历dataList,按每个样本的检出状态(是否检出)对物质进行分类
for (TestRecordSampleData record : dataList) {
String sampleNo = record.getSampleNo(); // 获取样本编号
String compoundName = record.getCompoundName(); // 获取化合物名称
allCompoundNames.add(compoundName); // 将化合物名称添加到所有化合物名称集合中
// 根据isDetected值将物质添加到相应的Map中
if (record.getIsDetected() == 1) {
detectedMap.computeIfAbsent(sampleNo, k -> new ArrayList<>()).add(compoundName); // 如果检出,将物质加入到检测的Map中
} else {
notDetectedMap.computeIfAbsent(sampleNo, k -> new ArrayList<>()).add(compoundName); // 如果未检出,将物质加入到未检测的Map中
}
}
// 4. 定义一个lambda函数,提取样本编号中的流水号(例如:"S001" -> "1号")
// 目的是生成以“号”结尾的样本编号格式。
Function<String, String> extractSampleNumber = sampleNo -> sampleNo.substring(sampleNo.lastIndexOf('-') + 1) + "号";
// 5. 处理“检出”数据
// 先根据样本编号分组相同的检出物质,之后生成相应的语句描述
List<String> detectedSentences = new ArrayList<>(); // 存储“检出”物质的描述
Map<Set<String>, List<String>> groupedDetectedSamples = new LinkedHashMap<>(); // 用来存储按物质分组的样本编号
// 遍历检测到的物质,将相同物质的样本编号进行分组
for (Map.Entry<String, List<String>> entry : detectedMap.entrySet()) {
Set<String> compoundSet = new HashSet<>(entry.getValue()); // 去重,保证每个物质只记录一次
groupedDetectedSamples.computeIfAbsent(compoundSet, k -> new ArrayList<>()).add(extractSampleNumber.apply(entry.getKey())); // 根据物质的组合来分组样本编号
}
// 遍历每个分组,生成对应的描述
for (Map.Entry<Set<String>, List<String>> entry : groupedDetectedSamples.entrySet()) {
String sampleNumbers = String.join("、", entry.getValue()); // 将所有样本编号合并为字符串
String compounds = String.join("、", entry.getKey()); // 将所有检出的物质合并为字符串
// 如果多个样本检出相同的物质,描述中使用“均检出”,否则使用“检出”
if (entry.getValue().size() > 1) {
detectedSentences.add(String.format("从%s检材样品中均检出%s成分", sampleNumbers, compounds)); // 多个样本检出
} else {
detectedSentences.add(String.format("从%s检材样品中检出%s成分", sampleNumbers, compounds)); // 单个样本检出
}
}
// 6. 处理“未检出”数据
// 先根据未检出的物质及样本编号进行分组,然后生成相应的描述
List<String> notDetectedSentences = new ArrayList<>(); // 存储“未检出”物质的描述
Map<Set<String>, List<String>> groupedNotDetectedSamples = new LinkedHashMap<>(); // 用来存储按物质分组的样本编号
// 遍历未检出的物质,找到未检出的样本并将其分组
for (Map.Entry<String, List<String>> entry : notDetectedMap.entrySet()) {
String sampleNo = entry.getKey(); // 获取样本编号
if (detectedMap.containsKey(sampleNo)) {
continue; // 如果该样本已经出现在检出组中,跳过,不再处理
}
Set<String> compoundSet = new HashSet<>(entry.getValue()); // 获取未检出的物质,去重
groupedNotDetectedSamples.computeIfAbsent(compoundSet, k -> new ArrayList<>()).add(extractSampleNumber.apply(sampleNo)); // 将未检出的物质分组
}
// 遍历每个未检出物质的分组,生成描述
for (Map.Entry<Set<String>, List<String>> entry : groupedNotDetectedSamples.entrySet()) {
String sampleNumbers = String.join("、", entry.getValue()); // 将未检出的样本编号合并为字符串
String compounds = String.join("、", entry.getKey()); // 将未检出的物质合并为字符串
// 如果多个样本未检出相同的物质,描述中使用“均未检出”,否则使用“未检出”
if (entry.getValue().size() > 1) {
notDetectedSentences.add(String.format("从%s检材样品中均未检出%s成分", sampleNumbers, compounds)); // 多个样本未检出
} else {
notDetectedSentences.add(String.format("从%s检材样品中未检出%s成分", sampleNumbers, compounds)); // 单个样本未检出
}
}
// 7. 将“检出”和“未检出”描述合并到最终结果中
List<String> finalSentences = new ArrayList<>(detectedSentences); // 先将检出物质的描述加入
finalSentences.addAll(notDetectedSentences); // 将未检出的描述添加到末尾
// 8. 将最终的描述字符串添加到结果数据Map中,字段名为"detectionStr"返回结果
return String.join(";", finalSentences);
}
public static void main(String[] args) {
List<TestRecordSampleData> list = Arrays.asList(
new TestRecordSampleData("1", "Sample1", "2025-1-1", "T1", "10", "5", "羟考酮", "0.5", 1.2, 5.5, 5.0, 0, "Analyte", "{}", "{}", 1, "Oxycodone"),
new TestRecordSampleData("2", "Sample1", "2025-1-1", "T1", "10", "4", "海洛因", "0.4", 1.1, 5.4, 5.0, 0, "Analyte", "{}", "{}", 1, "Heroin"),
new TestRecordSampleData("3", "Sample1", "2025-1-1", "T1", "10", "3", "四氢大麻酚", "0.6", 1.3, 5.6, 5.0, 0, "Analyte", "{}", "{}", 1, "THC"),
new TestRecordSampleData("4", "Sample2", "2025-1-2", "T2", "10", "5", "羟考酮", "0.5", 1.2, 5.5, 5.0, 0, "Analyte", "{}", "{}", 1, "Oxycodone"),
new TestRecordSampleData("5", "Sample2", "2025-1-2", "T2", "10", "4", "海洛因", "0.4", 1.1, 5.4, 5.0, 1, "Analyte", "{}", "{}", 1, "Heroin"),
new TestRecordSampleData("6", "Sample2", "2025-1-2", "T2", "10", "3", "四氢大麻酚", "0.6", 1.3, 5.6, 5.0, 0, "Analyte", "{}", "{}", 1, "THC"),
new TestRecordSampleData("7", "Sample3", "2025-1-3", "T3", "10", "5", "羟考酮", "0.5", 1.2, 5.5, 5.0, 1, "Analyte", "{}", "{}", 1, "Oxycodone"),
new TestRecordSampleData("8", "Sample3", "2025-1-3", "T3", "10", "4", "海洛因", "0.4", 1.1, 5.4, 5.0, 0, "Analyte", "{}", "{}", 1, "Heroin"),
new TestRecordSampleData("9", "Sample3", "2025-1-3", "T3", "10", "3", "四氢大麻酚", "0.6", 1.3, 5.6, 5.0, 1, "Analyte", "{}", "{}", 1, "THC"),
new TestRecordSampleData("10", "Sample4", "2025-1-4", "T4", "10", "5", "羟考酮", "0.5", 1.2, 5.5, 5.0, 0, "Analyte", "{}", "{}", 1, "Oxycodone"),
new TestRecordSampleData("11", "Sample4", "2025-1-4", "T4", "10", "4", "海洛因", "0.4", 1.1, 5.4, 5.0, 0, "Analyte", "{}", "{}", 1, "Heroin"),
new TestRecordSampleData("12", "Sample4", "2025-1-4", "T4", "10", "3", "四氢大麻酚", "0.6", 1.3, 5.6, 5.0, 0, "Analyte", "{}", "{}", 1, "THC"),
new TestRecordSampleData("10", "Sample4", "2025-1-5", "T4", "10", "5", "羟考酮", "0.5", 1.2, 5.5, 5.0, 0, "Analyte", "{}", "{}", 1, "Oxycodone"),
new TestRecordSampleData("11", "Sample4", "2025-1-5", "T4", "10", "4", "海洛因", "0.4", 1.1, 5.4, 5.0, 1, "Analyte", "{}", "{}", 1, "Heroin"),
new TestRecordSampleData("12", "Sample4", "2025-1-5", "T4", "10", "3", "四氢大麻酚", "0.6", 1.3, 5.6, 5.0, 0, "Analyte", "{}", "{}", 1, "THC"),
new TestRecordSampleData("10", "Sample4", "2025-1-6", "T4", "10", "5", "羟考酮", "0.5", 1.2, 5.5, 5.0, 1, "Analyte", "{}", "{}", 1, "Oxycodone"),
new TestRecordSampleData("11", "Sample4", "2025-1-6", "T4", "10", "4", "海洛因", "0.4", 1.1, 5.4, 5.0, 0, "Analyte", "{}", "{}", 1, "Heroin"),
new TestRecordSampleData("12", "Sample4", "2025-1-6", "T4", "10", "3", "四氢大麻酚", "0.6", 1.3, 5.6, 5.0, 0, "Analyte", "{}", "{}", 1, "THC"));
String detectionStr = new InspectRecordServiceImpl().buildInspectOpinion(list);
System.out.println(detectionStr);
}
}

@ -1907,4 +1907,20 @@ public class TestRecordSampleDataServiceImpl extends ServiceImpl<TestRecordSampl
}
return this.updateById(data) ? data : null;
}
@Override
public Comparator getSortBySampleNo() {
return Comparator.comparing(TestRecordSampleData::getSampleNo, (a, b) -> {
String[] partsA = a.split("-");
String[] partsB = b.split("-");
// 逐部分比较数值
for (int i = 0; i < 3; i++) {
int numA = Integer.parseInt(partsA[i]);
int numB = Integer.parseInt(partsB[i]);
if (numA != numB) return Integer.compare(numA, numB);
}
return 0; // 所有部分相同
}
);
}
}

@ -103,6 +103,23 @@ public class TestRecordServiceImpl extends ServiceImpl<TestRecordMapper, TestRec
List<DataSolutionSampleDTO> dataSolutionSampleDTOS = testRecordSampleDataMapper
.queryDataSolutionSampleDTOList(Wrappers.<DataSolutionSampleDTO>query()
.eq("si.business_id", businessId));
if (dataSolutionSampleDTOS.size() == 0) {
List<String> sampleIdList = sampleInfoService.lambdaQuery()
.eq(SampleInfo::getBusinessId, businessId)
.list()
.stream()
.map(SampleInfo::getId)
.collect(Collectors.toList());
for (String sampleId : sampleIdList) {
TestRecord record = this.lambdaQuery()
.like(TestRecord::getSampleTestList, sampleId)
.getEntity();
if (record != null) {
return record;
}
}
}
TestRecord testRecord = super.getById(dataSolutionSampleDTOS.get(0).getTestId());
return testRecord;
}

@ -0,0 +1,25 @@
package digital.laboratory.platform.inspection.vo;
import digital.laboratory.platform.inspection.entity.TestRecordSampleData;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class TestRecordSampleDataVO extends TestRecordSampleData {
/**
* 离子丰度比 | 峰面积之比
*/
private BigDecimal ionAbundanceRatio;
/**
* 离子丰度比相对偏差%| 计算离子丰度比 相对偏差 (目标物离子丰度比 - 标准物离子丰度比) / 标准物质离子丰度比 * 100
*/
private BigDecimal ionAbundanceRatioError;
/**
* 离子丰度比偏差是否在误差范围内
*/
private String ionAbundanceRatioWithinError;
}
Loading…
Cancel
Save