master
杨海航 5 days ago
parent 279b9a92bd
commit 21f359cb4f
  1. 3
      dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestRecord.java
  2. 10
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordSampleDataDocDTO.java
  3. 177
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/InspectRecordServiceImpl.java
  4. 4
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordServiceImpl.java

@ -93,4 +93,7 @@ public class TestRecord extends BaseEntity {
@ApiModelProperty("实验结束时间")
@JsonFormat(pattern = "yyyy/MM/dd", timezone = "GMT+8")
private LocalDate testEndDate;
@ApiModelProperty("业务Id,特指委托ID")
private String businessId;
}

@ -3,6 +3,8 @@ package digital.laboratory.platform.inspection.dto;
import digital.laboratory.platform.inspection.entity.TestRecordSampleData;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class TestRecordSampleDataDocDTO extends TestRecordSampleData {
@ -53,4 +55,12 @@ public class TestRecordSampleDataDocDTO extends TestRecordSampleData {
* 样本索引编号
*/
private String indexNum;
/**
* 质荷比(m/z) nps案件
* p 表示打印 (Print)
*/
private String pMassToChargeRatio;
}

@ -1,4 +1,5 @@
package digital.laboratory.platform.inspection.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
@ -37,6 +38,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -80,7 +82,7 @@ public class InspectRecordServiceImpl implements InspectRecordService {
/**
* 生成检验记录-贵阳禁毒
*
* @param businessId 委托id
* @param businessId 委托id
* @param materialType 标注当前委托的检材是尿液还是毛发
* @return
* @throws Exception
@ -141,19 +143,6 @@ public class InspectRecordServiceImpl implements InspectRecordService {
// 生成基础数据
HashMap<String, Object> data = buildCommonInspectRecordDocMap(entrustInfo, testRecord, materialType);
// 获取仪器设备数据(批量查询,减少数据库压力)
List<String> deviceIdList = testRecord.getDeviceIdList();
List<TestRecordInstrument> instruments = CollectionUtils.isEmpty(deviceIdList)
? Collections.emptyList()
: testRecordInstrumentService.list(Wrappers.<TestRecordInstrument>lambdaQuery()
.in(TestRecordInstrument::getId, deviceIdList));
data.put("instrumentName", CollectionUtils.isEmpty(instruments)
? "未找到仪器设备数据!"
: instruments.stream()
.map(i -> "\u3000\u3000" + i.getInstrumentName()) // 使用 Unicode 全角空格
.collect(Collectors.joining("\n")));
// 获取样品数据
List<TestRecordSampleData> dataList = testRecordSampleDataService.list(
@ -275,11 +264,138 @@ public class InspectRecordServiceImpl implements InspectRecordService {
.collect(Collectors.toList()));
// 返回处理后的数据
data.put("dataDtos", dataDtos);
data.put("sampleSize", dataDtos.size());
data.put("sampleSize", dataDtos.size() / 2);
data.put("inspectOpinion", this.buildInspectOpinion(dataList));
return data;
}
public Map<String, Object> buildInVitroRecordData(EntrustInfo entrustInfo, TestRecord testRecord) {
Map<String, Object> data = new HashMap<>();
// 1 按化合物名称分组 TestRecordSampleData
Map<String, List<TestRecordSampleData>> compoundSampleDataMap = testRecordSampleDataService
.lambdaQuery()
.eq(TestRecordSampleData::getTestId, testRecord.getId())
.list()
.stream()
.collect(Collectors.groupingBy(TestRecordSampleData::getCompoundName));
// 2 过滤出 "标准物质" 类别的试剂,并转换为 Map (key=药品名称, value=试剂VO)
List<String> reagentConsumablesList = testRecord.getReagentConsumablesList();
Map<String, TestRecordReagentVO> reagentMap = reagentConsumablesList.stream()
.map(testRecordReagentService::getVOById)
.filter(vo -> "标准物质".equals(vo.getCategory())) // 仅保留 "标准物质"
.collect(Collectors.toMap(vo -> vo.getDrug().getName(), vo -> vo));
List<TestRecordSampleDataDocDTO> dataDtos = new ArrayList<>();
// 3 遍历每种化合物,处理实验数据
for (Map.Entry<String, List<TestRecordSampleData>> entry : compoundSampleDataMap.entrySet()) {
String compoundName = entry.getKey();
List<TestRecordSampleData> sampleDataList = entry.getValue();
// 按 sampleType 分组(如 STD, Analyte)
Map<String, List<TestRecordSampleData>> sampleTypeMap = sampleDataList.stream()
.collect(Collectors.groupingBy(TestRecordSampleData::getSampleType));
// 获取标准样本(STD)
List<TestRecordSampleData> stdList = sampleTypeMap.get("STD");
if (stdList == null || stdList.isEmpty()) {
continue; // 没有 STD 样本,跳过该化合物
}
TestRecordSampleData stdSample = stdList.get(0);
// 4 获取 STD 样本的扩展数据 (以 MassToChargeRatio 为 key)
Map<BigDecimal, TestRecordSampleDataExpand> expandMap = testRecordSampledataExpandService.lambdaQuery()
.eq(TestRecordSampleDataExpand::getTestDataId, stdSample.getId())
.list()
.stream()
.collect(Collectors.toMap(TestRecordSampleDataExpand::getMassToChargeRatio, Function.identity()));
// 5 获取当前化合物对应的试剂,提取特征离子
TestRecordReagentVO reagentVO = reagentMap.get(compoundName);
if (reagentVO == null || reagentVO.getDrug().getCharacteristicIons() == null) {
continue; // 没有对应试剂或特征离子数据,跳过
}
String[] peaks = reagentVO.getDrug().getCharacteristicIons().split("、");
// 6 处理 "标样" 数据 (STD)
for (int i = 0; i < peaks.length; i++) {
String peak = (i == 0) ? peaks[i].substring(0, peaks[i].length() - 1) : peaks[i];
TestRecordSampleDataExpand expand = expandMap.get(new BigDecimal(peak));
if (expand != null) {
TestRecordSampleDataDocDTO dto = new TestRecordSampleDataDocDTO();
BeanUtils.copyProperties(stdSample, dto);
dto.setName("标样");
dto.setPTargetRtTime(dto.getTargetRtTime().toString());
dto.setPRtTimeError("±1");
dto.setPRtTimeWithinError("/");
dto.setPMassToChargeRatio(i == 0 ? peak + "(基峰)" : peak);
dto.setPIonAbundanceRatio(expand.getIonAbundanceRatio().toString());
dto.setPIonAbundanceRatioError(expand.getIonAbundanceRatioError().toString());
dto.setPIonAbundanceRatioWithinError(expand.getIonAbundanceRatioWithinError());
dto.setPIsDetected("/");
dataDtos.add(dto);
}
}
// 7 处理 "标样空白" 数据
for (String peak : peaks) {
TestRecordSampleDataDocDTO dto = new TestRecordSampleDataDocDTO();
dto.setName("标样空白");
dto.setCompoundName(compoundName);
dto.setPTargetRtTime("/");
dto.setPRtTimeError("/");
dto.setPRtTimeWithinError("/");
dto.setPMassToChargeRatio(peak.equals(peaks[0]) ? peak + "(基峰)" : peak);
dto.setPIonAbundanceRatio("/");
dto.setPIonAbundanceRatioError("/");
dto.setPIonAbundanceRatioWithinError(peak.equals(peaks[0]) ? "/" : "否");
dto.setPIsDetected("/");
dataDtos.add(dto);
}
// 8 处理 "Analyte" 样本
List<TestRecordSampleData> analyteList = sampleTypeMap.get("Analyte");
if (analyteList != null) {
analyteList.sort(testRecordSampleDataService.getSortBySampleNo()); // 按样本编号排序
for (TestRecordSampleData analyte : analyteList) {
Map<BigDecimal, TestRecordSampleDataExpand> analyteExpandMap = testRecordSampledataExpandService.lambdaQuery()
.eq(TestRecordSampleDataExpand::getTestDataId, analyte.getId())
.list()
.stream()
.collect(Collectors.toMap(TestRecordSampleDataExpand::getMassToChargeRatio, Function.identity()));
for (int i = 0; i < peaks.length; i++) {
String peak = (i == 0) ? peaks[i].substring(0, peaks[i].length() - 1) : peaks[i];
TestRecordSampleDataExpand expand = analyteExpandMap.get(new BigDecimal(peak));
if (expand != null) {
TestRecordSampleDataDocDTO dto = new TestRecordSampleDataDocDTO();
BeanUtils.copyProperties(analyte, dto);
dto.setPTargetRtTime(dto.getTargetRtTime().toString());
dto.setPRtTimeError(dto.getRtTimeWithinError());
dto.setPRtTimeWithinError(dto.getRtTimeWithinError());
dto.setPMassToChargeRatio(i == 0 ? peak + "(基峰)" : peak);
dto.setPIonAbundanceRatio(expand.getIonAbundanceRatio().toString());
dto.setPIonAbundanceRatioError(expand.getIonAbundanceRatioError().toString());
dto.setPIonAbundanceRatioWithinError(expand.getIonAbundanceRatioWithinError());
dto.setPIsDetected(dto.getIsDetected() == 1 ? "是" : "否");
dataDtos.add(dto);
}
}
}
}
}
// 9 返回处理后的数据
data.put("dataDtos", dataDtos);
return data;
}
public void buildIonPairAndCE(Map<String, Object> data, List<String> reagentIdList) {
List<IonPairAndCEVO> ionPairAndCEVOS = new ArrayList<>();
@ -387,14 +503,20 @@ public class InspectRecordServiceImpl implements InspectRecordService {
/**
* 生成常规毒品的检验记录贵阳禁毒
*/
public String generateCommonDrugInpectRecord(String entrustId) throws Exception {
Map<String, Object> docMap = buildCommonDrugDocMap(entrustId);
public String generateCommonDrugInpectRecord(String businessId) throws Exception {
Map<String, Object> docMap = buildCommonDrugDocMap(businessId);
EntrustInfo entrustInfo = entrustInfoService.getById(businessId);
TestRecord testRecord = testRecordService.lambdaQuery()
.eq(TestRecord::getBusinessId, businessId)
.one();
Map<String, Object> data = this.buildInVitroRecordData(entrustInfo, testRecord);
docMap.putAll(data);
String templatePath = "/template" + "/贵阳禁毒常规毒品检验记录模板.docx";
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
Configure config = Configure.builder().
bind("dataDtos", policy)
.build();
return buildDocFileAndUploadToOss(entrustId, templatePath, config, docMap);
return buildDocFileAndUploadToOss(businessId, templatePath, config, docMap);
}
/**
@ -402,8 +524,8 @@ public class InspectRecordServiceImpl implements InspectRecordService {
*
* @return
*/
private Map<String, Object> buildCommonDrugDocMap(String entrustId) {
EntrustInfo entrustInfo = entrustInfoService.getById(entrustId);
private Map<String, Object> buildCommonDrugDocMap(String businessId) {
EntrustInfo entrustInfo = entrustInfoService.getById(businessId);
// 这里因为检验记录实体并未关联业务id, 只能先查询实验数据,在通过实验数据获取到检验记录信息
TestRecord testRecord = testRecordService.getTestRecordByBusinessId(entrustInfo.getId());
@ -411,6 +533,7 @@ public class InspectRecordServiceImpl implements InspectRecordService {
// 封装数据到map中
Map<String, Object> docMap = buildCommonInspectRecordDocMap(entrustInfo, testRecord, "");
return docMap;
}
@ -461,6 +584,20 @@ public class InspectRecordServiceImpl implements InspectRecordService {
data.put("materialCharacterDesc", materialCharacterDesc);
data.put("materialIngredient", targetObjectStr);
// 获取仪器设备数据(批量查询,减少数据库压力)
List<String> deviceIdList = testRecord.getDeviceIdList();
List<TestRecordInstrument> instruments = CollectionUtils.isEmpty(deviceIdList)
? Collections.emptyList()
: testRecordInstrumentService.list(Wrappers.<TestRecordInstrument>lambdaQuery()
.in(TestRecordInstrument::getId, deviceIdList));
data.put("instrumentName", CollectionUtils.isEmpty(instruments)
? "未找到仪器设备数据!"
: instruments.stream()
.map(i -> "\u3000\u3000" + i.getInstrumentName()) // 使用 Unicode 全角空格
.collect(Collectors.joining("\n")));
// 设置使用的标准物质和试剂
List<TestRecordReagent> references = testRecordReagentService.list(Wrappers.<TestRecordReagent>lambdaQuery()
.in(TestRecordReagent::getId, testRecord.getReagentConsumablesList())

@ -161,6 +161,9 @@ public class TestRecordServiceImpl extends ServiceImpl<TestRecordMapper, TestRec
//通过业务ID创建实验
} else if (testRecord.getBusinessDtoList() != null && testRecord.getBusinessDtoList().size() > 0) {
if (testRecord.getBusinessDtoList().size()>1){
throw new RuntimeException("一次只能选择一个业务!");
}
List<BusinessDto> businessDtoList = testRecord.getBusinessDtoList();
this.judgmentBusinessType(businessDtoList);//判断是否有不同类型的业务
businessDtoList.forEach(item -> {
@ -183,6 +186,7 @@ public class TestRecordServiceImpl extends ServiceImpl<TestRecordMapper, TestRec
}
sampleInfoService.updateBatchById(sampleInfos);
}
testRecord.setBusinessId(testRecord.getBusinessDtoList().get(0).getBusinessId());
testRecord.setTestUserId(dlpUser.getId());
testRecord.setTestSerialNumber(this.createTestNumber());
testRecord.setSampleTestList(sampleIdList);

Loading…
Cancel
Save