@@ -12,6 +12,8 @@ import digital.laboratory.platform.inspection.entity.TestRecordInstrument;
import digital.laboratory.platform.inspection.entity.TestRecordMethod ;
import digital.laboratory.platform.inspection.entity.TestRecordReagent ;
import digital.laboratory.platform.inspection.entity.TestRecordSampleData ;
import digital.laboratory.platform.inspection.enums.BusinessType ;
import digital.laboratory.platform.inspection.event.PushDataToLabsCareEvent ;
import digital.laboratory.platform.inspection.mapper.TestRecordSampleDataMapper ;
import digital.laboratory.platform.inspection.service.* ;
import digital.laboratory.platform.inspection.vo.TestRecordReagentVO ;
@@ -84,14 +86,19 @@ public class PushDataToLabsCareServiceImpl implements PushDataToLabsCareService
// "#NULL#" 作为空数据的占位符, 对于系统中没有的信息以占位符代替
public final static String NULL_PLACEHOLDER = " #NULL# " ;
// 生物检材定性检验记录标识
private final static String BIOLOGY_QUALITATIVE_RECORD = " BiologyQualitativeRecord " ;
// 普通检材定性记录非红外报告标识
private final static String NON_INFRARED_GENERAL_QUALITATIVE_RECORD = " nonInfraredGeneralQualitativeRecord " ;
/**
* 做一个定时推送,对于推送失败的委托进行重新推送, 每天凌晨1点推送
*/
// @Scheduled(cron = "30 * * * * ?") // 测试
@Scheduled ( cron = " 0 0 2 * * ? " ) // 每天凌晨 2 点执行
public void timingPushDataToLabsCare ( ) {
log . info ( " 定时推送数据到LabsCare...... " ) ;
// 查询检验鉴定推送失败的委托
List < EntrustInfo > entrustList = entrustInfoService . list (
Wrappers . < EntrustInfo > lambdaQuery ( )
@@ -120,18 +127,68 @@ public class PushDataToLabsCareServiceImpl implements PushDataToLabsCareService
EntrustInfo entrustInfo = entrustInfoMap . get ( testRecord . getBusinessId ( ) ) ;
String pushFlag = entrustInfo . getPushFlag ( ) ;
if ( StrUtil . isBlank ( pushFlag ) ) {
if ( testRecord . getBusinessType ( ) . equals ( BusinessType . BOINT_CASE . getBusinessType ( ) ) ) {
pushBiologyQualitativeRecordData ( testRecord . getId ( ) ) ;
} else if ( testRecord . getBusinessType ( ) . equals ( BusinessType . NPS_CASE . getBusinessType ( ) ) ) {
pushNonInfraredGeneralQualitativeRecordData ( testRecord . getId ( ) ) ;
}
} else {
List < String > flagList = StrUtil . split ( pushFlag , StrUtil . COMMA ) . stream ( ) . filter ( str - > str . contains ( " false " ) ) . collect ( Collectors . toList ( ) ) ;
for ( String flag : flagList ) {
if ( flag . contains ( BIOLOGY_QUALITATIVE_RECORD ) ) {
pushBiologyQualitativeRecordData ( testRecord . getId ( ) ) ;
} else {
pushNonInfraredGeneralQualitativeRecordData ( testRecord . getId ( ) ) ;
}
}
}
}
}
/**
* 推送普通检材定性记录非红外报告数据
* @param testId 实验id
*/
@Override
public void pushNonInfraredGeneralQualitativeRecordData ( String testId ) {
TestRecord testRecord = validTestRecord ( testId ) ;
if ( testRecord = = null ) return ;
// 获取委托信息
EntrustInfo entrustInfo = entrustInfoService . getById ( testRecord . getBusinessId ( ) ) ;
JSONObject recordJsonPayload = buildNonInfraredGeneralQualitativeRecordJsonPayload ( entrustInfo , testRecord ) ;
String successFlag = NON_INFRARED_GENERAL_QUALITATIVE_RECORD + " :true " ;
String failureFlag = NON_INFRARED_GENERAL_QUALITATIVE_RECORD + " :false " ;
try {
ResponseEntity < String > response = exchangeRemoteApi ( recordJsonPayload , apiPathProperties . getBiologyQualitativeRecord ( ) ) ;
if ( response . getStatusCode ( ) . is2xxSuccessful ( ) & & response . getBody ( ) . contains ( " \" status \" :200 " ) ) {
updatePushFlag ( entrustInfo , NON_INFRARED_GENERAL_QUALITATIVE_RECORD , successFlag ) ;
log . info ( " 推送普通检材定性记录非红外报告数据成功, 受理编号: {}, 响应: {} " , entrustInfo . getAcceptNo ( ) , response . getBody ( ) ) ;
} else {
updatePushFlag ( entrustInfo , NON_INFRARED_GENERAL_QUALITATIVE_RECORD , failureFlag ) ;
log . warn ( " 推送普通检材定性记录非红外报告数据失败, 受理编号: {}, 状态码: {}, 响应: {} " ,
entrustInfo . getAcceptNo ( ) , response . getStatusCode ( ) , response . getBody ( ) ) ;
}
} catch ( RestClientException e ) {
log . error ( " 推送普通检材定性记录非红外报告数据到 LabsCare 失败, 受理编号: {} " , entrustInfo . getAcceptNo ( ) , e ) ;
}
}
/**
* 验证并获取有效的实验信息
*
* @param testId 测试记录的唯一标识符
* @return 如果存在有效的测试记录, 则返回该测试记录; 否则返回null
*/
private TestRecord validTestRecord ( String testId ) {
TestRecord testRecord = testRecordService . getById ( testId ) ;
if ( testRecord = = null ) {
log . error ( " 实验id为 [{}] 的实验信息查询为空! " , testId ) ;
return null ;
}
}
return testRecord ;
}
/**
@@ -140,11 +197,8 @@ public class PushDataToLabsCareServiceImpl implements PushDataToLabsCareService
*/
@Override
public void pushBiologyQualitativeRecordData ( String testId ) {
TestRecord testRecord = t estRecordService . getById ( testId ) ;
if ( testRecord = = null ) {
log . error ( " 实验id为 [{}] 的实验信息查询为空! " , testId ) ;
return ;
}
TestRecord testRecord = validT estRecord( testId ) ;
if ( testRecord = = null ) return ;
// 获取委托信息
EntrustInfo entrustInfo = entrustInfoService . getById ( testRecord . getBusinessId ( ) ) ;
@@ -168,6 +222,13 @@ public class PushDataToLabsCareServiceImpl implements PushDataToLabsCareService
}
}
/**
* 构建生物检材定性记录Json数据
*
* @param entrustInfo 委托信息
* @param testRecord 测试记录
* @return 构建好的Json对象
*/
private JSONObject buildBiologyQualitativeRecordJsonPayload ( EntrustInfo entrustInfo , TestRecord testRecord ) {
// 查询封装需要用到的数据
List < SampleInfo > sampleInfoList = sampleInfoService
@@ -192,44 +253,15 @@ public class PushDataToLabsCareServiceImpl implements PushDataToLabsCareService
// 获取检测人用户信息
SysUser testUser = commonFeignService . remoteGetUserById ( testRecord . getTestUserId ( ) ) ;
// 检测数据信息
Map < String , List < TestRecordSampleDataVO > > testDataGroupBySampleNO = testRecordSampleDataMapper
. queryTestRecordSampleDataVOList ( Wrappers . < TestRecordSampleData > lambdaQuery ( )
. eq ( TestRecordSampleData : : getTestId , testRecord . getId ( ) )
. eq ( TestRecordSampleData : : getSampleType , TestRecordSampleDataConstant . SAMPLE_TYPE_ANALYTE )
) // 数据库查询, 这个是非标准物质的检测数据
. stream ( ) . collect ( Collectors . groupingBy ( TestRecordSampleDataVO : : getSampleNo ) ) ; // 根据查询出来的结果进行分组
// 获取样品检测数据,按照样品编号分组
Map < String , List < TestRecordSampleDataVO > > testDataGroupBySampleNO = fetchTestDataGroupBySampleNo ( testRecord ) ;
Map < String , TestRecordSampleDataVO > stdTestDataMap = testRecordSampleDataMapper
. queryTestRecordSampleDataVOList ( Wrappers . < TestRecordSampleData > lambdaQuery ( )
. eq ( TestRecordSampleData : : getTestId , testRecord . getId ( ) )
. eq ( TestRecordSampleData : : getSampleType , TestRecordSampleDataConstant . SAMPLE_TYPE_STD )
) // 数据库查询, 这个是非标准物质的检测数据
. stream ( ) . collect ( Collectors . toMap ( TestRecordSampleDataVO : : getCompoundName , Function . identity ( ) ) ) ; // 根据查询出来的结果进行分组
// 获取标准物质的测试数据
Map < String , TestRecordSampleDataVO > stdTestDataMap = fetchStdTestData ( testRecord ) ;
// 查询 使用的仪器
List < String> deviceIdList = testRecord . getDeviceIdList ( ) ;
List < TestRecordInstrument > instruments = CollectionUtils . isEmpty ( deviceIdList )
? Collections . emptyList ( )
: testRecordInstrumentService . list ( Wrappers . < TestRecordInstrument > lambdaQuery ( )
. in ( TestRecordInstrument : : getId , deviceIdList ) ) ;
String useInstrumentNameStr = CollectionUtils . isEmpty ( instruments )
? NULL_PLACEHOLDER
: instruments . stream ( )
. map ( TestRecordInstrument : : getInstrumentName )
. collect ( Collectors . joining ( " , " ) ) ;
// 使用的方法
List < String > testMethodList = testRecord . getTestMethodList ( ) ;
List < TestRecordMethod > testRecordMethodList = CollectionUtils . isEmpty ( testMethodList )
? Collections . emptyList ( )
: testRecordMethodService . list ( Wrappers . < TestRecordMethod > lambdaQuery ( )
. in ( TestRecordMethod : : getId , testMethodList ) ) ;
String useMethodNameStr = CollectionUtils . isEmpty ( instruments )
? NULL_PLACEHOLDER
: testRecordMethodList . stream ( )
. map ( TestRecordMethod : : getMethodName )
. collect ( Collectors . joining ( " , " ) ) ;
// 获取 使用的仪器和方法
String useInstrumentNameStr = getInstrumentNames ( testRecord ) ;
String useMethodNameStr = getMethodNames ( testRecord ) ;
// 开始封装数据参数
JSONObject jsonObject = new JSONObject ( ) ;
@@ -304,6 +336,93 @@ public class PushDataToLabsCareServiceImpl implements PushDataToLabsCareService
return jsonObject ;
}
/**
* 普通检材定性记录 非红外报告 的json 数据
*
* @param entrustInfo 委托信息
* @param testRecord 测试记录
* @return 构建好的Json对象
*/
private JSONObject buildNonInfraredGeneralQualitativeRecordJsonPayload ( EntrustInfo entrustInfo , TestRecord testRecord ) {
// 查询封装需要用到的数据
List < SampleInfo > sampleInfoList = sampleInfoService
. lambdaQuery ( )
. in ( SampleInfo : : getId , testRecord . getSampleTestList ( ) )
. list ( ) ;
// 对受理编号进行分隔
List < String > splitAcceptNo = StrUtil . split ( entrustInfo . getAcceptNo ( ) , " - " ) ;
// 设置使用的标准物质和试剂
List < TestRecordReagentVO > references = testRecordReagentService . voListByWrapper ( Wrappers . < TestRecordReagent > lambdaQuery ( )
. in ( TestRecordReagent : : getId , testRecord . getReagentConsumablesList ( ) )
. eq ( TestRecordReagent : : getCategory , " 标准物质 " ) ) ;
// 本次实验使用的标准品
String stdStr = references . stream ( ) . map ( TestRecordReagentVO : : getReagentConsumableName ) . collect ( Collectors . joining ( " 、 " ) ) ;
// 获取检测人用户信息
SysUser testUser = commonFeignService . remoteGetUserById ( testRecord . getTestUserId ( ) ) ;
// 获取样品检测数据,按照样品编号分组
Map < String , List < TestRecordSampleDataVO > > testDataGroupBySampleNO = fetchTestDataGroupBySampleNo ( testRecord ) ;
// 获取标准物质的测试数据
Map < String , TestRecordSampleDataVO > stdTestDataMap = fetchStdTestData ( testRecord ) ;
// 获取使用的仪器和方法
String useInstrumentNameStr = getInstrumentNames ( testRecord ) ;
String useMethodNameStr = getMethodNames ( testRecord ) ;
// 开始封装数据参数
JSONObject jsonObject = new JSONObject ( ) ;
jsonObject . set ( " jcxz " , inspectRecordService . buildMaterialCharacterDesc ( sampleInfoList ) ) ; // 检材性状描述
jsonObject . set ( " jdwsh " , String . format ( " [%s]%s号 " , splitAcceptNo . get ( 0 ) , splitAcceptNo . get ( 1 ) ) ) ; // 鉴定文书号
jsonObject . set ( " jysj " , testRecord . getTestStartDate ( ) . format ( formatter ) ) ; // 检验时间
jsonObject . set ( " jyy1qm " , testUser . getName ( ) ) ; // 检测人1
jsonObject . set (
" jyyq " ,
String . format ( " 对所送检材中是否含有 %s 成分进行定性检测 " , stdStr )
) ; // 检验要求,根据模板上的值来生成
jsonObject . set ( " sjr1 " , entrustInfo . getDeliver1Name ( ) ) ; // 送检人1
jsonObject . set ( " sjr2 " , entrustInfo . getDeliver2Name ( ) ) ; // 送检人2
jsonObject . set ( " slrq " , entrustInfo . getAcceptDate ( ) . format ( formatter ) ) ; // 受理日期
jsonObject . set ( " sprqm " , testUser . getName ( ) ) ; // 检测人2
jsonObject . set ( " tpfj " , NULL_PLACEHOLDER ) ; // 图谱
jsonObject . set ( " wtdw " , entrustInfo . getEntrustDepartment ( ) ) ;
// 普通检材定性记录 非红外样品信息
List < JSONObject > sampleJsonList = new ArrayList < > ( ) ;
testDataGroupBySampleNO . forEach ( ( sampleNo , testDataList ) - > {
JSONObject sampleJson = new JSONObject ( ) ;
sampleJson . set ( " caseName " , sampleNo ) ; // 样品编号
// 普通检材定性记录 非红外检测信息
List < JSONObject > gauging = testDataList . stream ( ) . map ( data - > {
JSONObject testDataJson = new JSONObject ( ) ;
testDataJson . set ( " blsjxdwc " , data . getRtTimeError ( ) ) ; // 保留时间相对误差(%)
testDataJson . set ( " swbzgzyzb " , NULL_PLACEHOLDER ) ; // 标准工作溶液制备
TestRecordSampleDataVO stdData = stdTestDataMap . get ( data . getCompoundName ( ) ) ;
testDataJson . set ( " bzwzblsj " , stdData . getTargetRtTime ( ) ) ; // 标准物质保留时间( min)
testDataJson . set ( " bzwzwb " , stdData . getCompoundName ( ) ) ; // 标准物质名称
testDataJson . set ( " swdcypzb " , NULL_PLACEHOLDER ) ; // 待测样品制备
testDataJson . set ( " dxff " , useMethodNameStr ) ; // 所用的方法
testDataJson . set ( " dxyq " , useInstrumentNameStr ) ; // 使用仪器
testDataJson . set ( " jdyj " , inspectRecordService . buildInspectOpinion ( Collections . singletonList ( TestRecordSampleDataConverter . voToEntity ( data ) ) ) ) ;
testDataJson . set ( " jgpd " , data . getWhetherCheckOut ( ) ) ; // 结果判定
testDataJson . set ( " jysj " , testRecord . getTestStartDate ( ) . format ( formatter ) ) ; // 检验时间
testDataJson . set ( " jytj " , NULL_PLACEHOLDER ) ; // 进样条件
testDataJson . set ( " mbwblsj " , data . getTargetRtTime ( ) ) ; // 目标物保留时间( min)
testDataJson . set ( " rjwb " , NULL_PLACEHOLDER ) ; // 溶剂
testDataJson . set ( " sj " , NULL_PLACEHOLDER ) ; // 上机
testDataJson . set ( " spz " , NULL_PLACEHOLDER ) ; // 仪器条件-色谱柱
testDataJson . set ( " zptppd " , NULL_PLACEHOLDER ) ; // 质谱图匹配度(%)
testDataJson . set ( " zw " , NULL_PLACEHOLDER ) ; // 柱温
return testDataJson ;
} ) . collect ( Collectors . toList ( ) ) ;
sampleJson . set ( " gauging " , gauging ) ; // 生物检材定性记录检测信息
sampleJsonList . add ( sampleJson ) ;
} ) ;
jsonObject . set ( " sample " , sampleJsonList ) ;
return jsonObject ;
}
/**
* 通过POST请求与远程API进行交互
@@ -353,4 +472,73 @@ public class PushDataToLabsCareServiceImpl implements PushDataToLabsCareService
. set ( EntrustInfo : : getPushFlag , String . join ( " , " , flagList ) ) ) ;
}
/**
* 根据实验记录中的样本编号对检验数据进行分组。
*
* @param testRecord 测试记录对象
* @return 包含分组后的测试数据映射关系,键为样本编号,值为样本编号对应的测试数据列表
*/
private Map < String , List < TestRecordSampleDataVO > > fetchTestDataGroupBySampleNo ( TestRecord testRecord ) {
return testRecordSampleDataMapper . queryTestRecordSampleDataVOList ( Wrappers . < TestRecordSampleData > lambdaQuery ( )
. eq ( TestRecordSampleData : : getTestId , testRecord . getId ( ) )
. eq ( TestRecordSampleData : : getSampleType , TestRecordSampleDataConstant . SAMPLE_TYPE_ANALYTE ) )
. stream ( )
. collect ( Collectors . groupingBy ( TestRecordSampleDataVO : : getSampleNo ) ) ;
}
/**
* 根据实验id获取标准测试数据
*
* @param testRecord 测试记录对象
* @return 标准测试数据的Map集合, 键为化合物名称, 值为TestRecordSampleDataVO对象
*/
private Map < String , TestRecordSampleDataVO > fetchStdTestData ( TestRecord testRecord ) {
return testRecordSampleDataMapper . queryTestRecordSampleDataVOList ( Wrappers . < TestRecordSampleData > lambdaQuery ( )
. eq ( TestRecordSampleData : : getTestId , testRecord . getId ( ) )
. eq ( TestRecordSampleData : : getSampleType , TestRecordSampleDataConstant . SAMPLE_TYPE_STD ) )
. stream ( )
. collect ( Collectors . toMap ( TestRecordSampleDataVO : : getCompoundName , Function . identity ( ) ) ) ;
}
/**
* 根据测试记录获取仪器名称列表
*
* @param testRecord 测试记录对象
* @return 仪器名称列表, 若列表为空则返回NULL_PLACEHOLDER
*/
private String getInstrumentNames ( TestRecord testRecord ) {
List < String > deviceIdList = testRecord . getDeviceIdList ( ) ;
List < TestRecordInstrument > instruments = CollectionUtils . isEmpty ( deviceIdList )
? Collections . emptyList ( )
: testRecordInstrumentService . list ( Wrappers . < TestRecordInstrument > lambdaQuery ( )
. in ( TestRecordInstrument : : getId , deviceIdList ) ) ;
return CollectionUtils . isEmpty ( instruments )
? NULL_PLACEHOLDER
: instruments . stream ( )
. map ( TestRecordInstrument : : getInstrumentName )
. collect ( Collectors . joining ( " , " ) ) ;
}
/**
* 获取方法名称列表,用逗号分隔
*
* @param testRecord 测试记录对象
* @return 方法名称列表, 用逗号分隔, 若为空则返回NULL_PLACEHOLDER
*/
private String getMethodNames ( TestRecord testRecord ) {
List < String > testMethodList = testRecord . getTestMethodList ( ) ;
List < TestRecordMethod > testRecordMethodList = CollectionUtils . isEmpty ( testMethodList )
? Collections . emptyList ( )
: testRecordMethodService . list ( Wrappers . < TestRecordMethod > lambdaQuery ( )
. in ( TestRecordMethod : : getId , testMethodList ) ) ;
return CollectionUtils . isEmpty ( testRecordMethodList )
? NULL_PLACEHOLDER
: testRecordMethodList . stream ( )
. map ( TestRecordMethod : : getMethodName )
. collect ( Collectors . joining ( " , " ) ) ;
}
}