@@ -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 entrust Id) throws Exception {
Map < String , Object > docMap = buildCommonDrugDocMap ( entrust Id) ;
public String generateCommonDrugInpectRecord ( String business Id) throws Exception {
Map < String , Object > docMap = buildCommonDrugDocMap ( business Id) ;
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 ( entrust Id, templatePath , config , docMap ) ;
return buildDocFileAndUploadToOss ( business Id, templatePath , config , docMap ) ;
}
/**
@@ -402,8 +524,8 @@ public class InspectRecordServiceImpl implements InspectRecordService {
*
* @return
*/
private Map < String , Object > buildCommonDrugDocMap ( String entrust Id) {
EntrustInfo entrustInfo = entrustInfoService . getById ( entrust Id) ;
private Map < String , Object > buildCommonDrugDocMap ( String business Id) {
EntrustInfo entrustInfo = entrustInfoService . getById ( business Id) ;
// 这里因为检验记录实体并未关联业务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 ( ) )