|
|
|
@ -33,6 +33,8 @@ import digital.laboratory.platform.sys.enums.entrust.EntrustBiologyType; |
|
|
|
|
import feign.Response; |
|
|
|
|
import org.apache.commons.io.output.ByteArrayOutputStream; |
|
|
|
|
import org.apache.poi.xwpf.usermodel.XWPFTable; |
|
|
|
|
import org.apache.poi.xwpf.usermodel.XWPFTableCell; |
|
|
|
|
import org.apache.poi.xwpf.usermodel.XWPFTableRow; |
|
|
|
|
import org.springframework.beans.BeanUtils; |
|
|
|
|
import org.springframework.mock.web.MockMultipartFile; |
|
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
@ -125,17 +127,8 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
System.out.println(String.format("转换为 PDF 结束")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 生成生物样本检验记录数据map |
|
|
|
|
* |
|
|
|
|
* @param entrustInfo 委托实体信息 |
|
|
|
|
* @param materialType 检材类型 |
|
|
|
|
* @return |
|
|
|
|
* @throws Exception |
|
|
|
|
*/ |
|
|
|
|
public Map<String, Object> buildInVivoRecordData(EntrustInfo entrustInfo, String materialType) throws Exception { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取检验记录信息
|
|
|
|
|
TestRecord testRecord = testRecordService.getTestRecordByBusinessId(entrustInfo.getId()); |
|
|
|
|
|
|
|
|
@ -146,7 +139,6 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
// 生成基础数据
|
|
|
|
|
HashMap<String, Object> data = buildCommonInspectRecordDocMap(entrustInfo, testRecord, materialType); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取样品数据
|
|
|
|
|
List<TestRecordSampleData> dataList = testRecordSampleDataService.list( |
|
|
|
|
Wrappers.<TestRecordSampleData>lambdaQuery().eq(TestRecordSampleData::getTestId, testRecord.getId())); |
|
|
|
@ -179,13 +171,13 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
TestRecordSampleDataDocDTO blankVo = new TestRecordSampleDataDocDTO(); |
|
|
|
|
blankVo.setName("空白" + materialType); |
|
|
|
|
blankVo.setCompoundName(compoundName); |
|
|
|
|
blankVo.setPTargetRtTime("/"); |
|
|
|
|
blankVo.setPRtTimeError("/"); |
|
|
|
|
blankVo.setPRtTimeWithinError("否"); |
|
|
|
|
blankVo.setPIonAbundanceRatio("/"); |
|
|
|
|
blankVo.setPIonAbundanceRatioError("/"); |
|
|
|
|
blankVo.setPIonAbundanceRatioWithinError("否"); |
|
|
|
|
blankVo.setPIsDetected("否"); |
|
|
|
|
blankVo.setPTargetRtTime("/"); // 设置空值为"/"
|
|
|
|
|
blankVo.setPRtTimeError("/"); // 设置空值为"/"
|
|
|
|
|
blankVo.setPRtTimeWithinError("否"); // 默认"否"
|
|
|
|
|
blankVo.setPIonAbundanceRatio("/"); // 设置空值为"/"
|
|
|
|
|
blankVo.setPIonAbundanceRatioError("/"); // 设置空值为"/"
|
|
|
|
|
blankVo.setPIonAbundanceRatioWithinError("否"); // 默认"否"
|
|
|
|
|
blankVo.setPIsDetected("否"); // 默认"否"
|
|
|
|
|
dataDtos.add(blankVo); |
|
|
|
|
|
|
|
|
|
// 根据样品类型分组
|
|
|
|
@ -197,22 +189,24 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
TestRecordSampleData std = map.get("STD").get(0); |
|
|
|
|
TestRecordSampleDataDocDTO stdVo = new TestRecordSampleDataDocDTO(); |
|
|
|
|
BeanUtils.copyProperties(std, stdVo); |
|
|
|
|
|
|
|
|
|
List<TestRecordSampleDataExpand> expandList = dataExpandMap.get(std.getId()); |
|
|
|
|
if (expandList != null) { |
|
|
|
|
for (TestRecordSampleDataExpand expand : expandList) { |
|
|
|
|
if (!expand.getBasePeak()) { |
|
|
|
|
stdVo.setPIonAbundanceRatio(expand.getIonAbundanceRatio().toString()); |
|
|
|
|
stdVo.setPIonAbundanceRatioError("/"); |
|
|
|
|
stdVo.setPIonAbundanceRatioWithinError("/"); |
|
|
|
|
stdVo.setPIonAbundanceRatio(expand.getIonAbundanceRatio() != null ? expand.getIonAbundanceRatio().toString() : "/"); |
|
|
|
|
stdVo.setPIonAbundanceRatioError("/"); // 设置空值为"/"
|
|
|
|
|
stdVo.setPIonAbundanceRatioWithinError("/"); // 设置空值为"/"
|
|
|
|
|
break; // 只取第一个符合条件的扩展数据
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
stdVo.setName("空白" + materialType + "加标"); |
|
|
|
|
stdVo.setPTargetRtTime(std.getTargetRtTime().toString()); |
|
|
|
|
stdVo.setPRtTimeError("/"); |
|
|
|
|
stdVo.setPRtTimeWithinError("/"); |
|
|
|
|
stdVo.setPIsDetected("是"); |
|
|
|
|
stdVo.setPTargetRtTime(std.getTargetRtTime() != null ? std.getTargetRtTime().toString() : "/"); |
|
|
|
|
stdVo.setPRtTimeError("/"); // 设置空值为"/"
|
|
|
|
|
stdVo.setPRtTimeWithinError("/"); // 设置空值为"/"
|
|
|
|
|
stdVo.setPIsDetected("是"); // 默认"是"
|
|
|
|
|
stdVo.setCompoundName(compoundName); |
|
|
|
|
dataDtos.add(stdVo); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -226,38 +220,43 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
TestRecordSampleData item = analyte.get(i); |
|
|
|
|
TestRecordSampleDataDocDTO vo = new TestRecordSampleDataDocDTO(); |
|
|
|
|
BeanUtils.copyProperties(item, vo); |
|
|
|
|
vo.setPTargetRtTime(vo.getTargetRtTime().toString()); |
|
|
|
|
vo.setPRtTimeError(vo.getRtTimeError().toString()); |
|
|
|
|
vo.setPRtTimeWithinError(vo.getRtTimeWithinError().toString()); |
|
|
|
|
vo.setPIsDetected(item.getIsDetected() == 1 ? "是" : "否"); |
|
|
|
|
|
|
|
|
|
vo.setPTargetRtTime(item.getTargetRtTime() != null ? item.getTargetRtTime().toString() : "/"); |
|
|
|
|
vo.setPRtTimeError(item.getRtTimeError() != null ? item.getRtTimeError().toString() : "/"); |
|
|
|
|
vo.setPRtTimeWithinError(item.getRtTimeWithinError() != null ? item.getRtTimeWithinError().toString() : "/"); |
|
|
|
|
vo.setPIsDetected(item.getIsDetected() != null && item.getIsDetected() == 1 ? "是" : "否"); |
|
|
|
|
|
|
|
|
|
List<TestRecordSampleDataExpand> expandList = dataExpandMap.get(item.getId()); |
|
|
|
|
if (expandList != null) { |
|
|
|
|
for (TestRecordSampleDataExpand expand : expandList) { |
|
|
|
|
if (!expand.getBasePeak()) { |
|
|
|
|
vo.setPIonAbundanceRatio(expand.getIonAbundanceRatio().toString()); |
|
|
|
|
vo.setPIonAbundanceRatioError(expand.getIonAbundanceRatioError().toString()); |
|
|
|
|
vo.setPIonAbundanceRatioWithinError(expand.getIonAbundanceRatioWithinError()); |
|
|
|
|
vo.setPIonAbundanceRatio(expand.getIonAbundanceRatio() != null ? expand.getIonAbundanceRatio().toString() : "/"); |
|
|
|
|
vo.setPIonAbundanceRatioError(expand.getIonAbundanceRatioError() != null ? expand.getIonAbundanceRatioError().toString() : "/"); |
|
|
|
|
vo.setPIonAbundanceRatioWithinError(expand.getIonAbundanceRatioWithinError() != null ? expand.getIonAbundanceRatioWithinError() : "/"); |
|
|
|
|
break; // 只取第一个符合条件的扩展数据
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 重新命名样品
|
|
|
|
|
vo.setName((dataList |
|
|
|
|
.stream() |
|
|
|
|
.collect(Collectors.groupingBy(TestRecordSampleData::getSampleNo)) |
|
|
|
|
.keySet() |
|
|
|
|
.size() == 1) ? "检材样品" : (i + 1) + "号检材样品"); |
|
|
|
|
vo.setCompoundName(compoundName); |
|
|
|
|
dataVOS.add(vo); |
|
|
|
|
} |
|
|
|
|
dataDtos.addAll(dataVOS); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 加入图谱序号值
|
|
|
|
|
int indexNum = 1; |
|
|
|
|
for (int i = 0; i < dataDtos.size(); i++) { |
|
|
|
|
dataDtos.get(i).setIndexNum(String.valueOf(indexNum++)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.buildIonPairAndCE(data, testRecordReagentService |
|
|
|
|
.list(Wrappers.<TestRecordReagent>lambdaQuery() |
|
|
|
|
.in(TestRecordReagent::getId, testRecord.getReagentConsumablesList()) |
|
|
|
@ -265,9 +264,11 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
.stream() |
|
|
|
|
.map(item -> item.getId()) |
|
|
|
|
.collect(Collectors.toList())); |
|
|
|
|
|
|
|
|
|
// 返回处理后的数据
|
|
|
|
|
data.put("dataDtos", dataDtos); |
|
|
|
|
data.put("sampleSize", dataDtos.size() / 2); |
|
|
|
|
data.put("compoundSize", dataDtos.stream().collect(Collectors.groupingBy(TestRecordSampleData::getCompoundName)).size()); |
|
|
|
|
data.put("type", "inVivo"); |
|
|
|
|
data.put("inspectOpinion", this.buildInspectOpinion(testRecordSampleDataService |
|
|
|
|
.lambdaQuery() |
|
|
|
|
.eq(TestRecordSampleData::getTestId, testRecord.getId()) |
|
|
|
@ -276,6 +277,7 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
return data; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Map<String, Object> buildInVitroRecordData(EntrustInfo entrustInfo, TestRecord testRecord, Map<String, Object> data) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -423,6 +425,7 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
// 9️⃣ 返回处理后的数据
|
|
|
|
|
data.put("dataDtos", dataDtos); |
|
|
|
|
data.put("sampleSize", dataDtos.size()); |
|
|
|
|
data.put("type", "inVitro"); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
Map<Integer, List<TestRecordSampleData>> isDetectedMap = testRecordSampleDataService |
|
|
|
@ -473,12 +476,12 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
if (!isDetectedStrs.isEmpty()) { |
|
|
|
|
data.put("isDetectedStrs", "阳性结果:" + "\n" + isDetectedStrs.stream() |
|
|
|
|
.map(item -> "\u3000\u3000" + item) |
|
|
|
|
.collect(Collectors.joining("\u2611"))); |
|
|
|
|
.collect(Collectors.joining("\n"))); |
|
|
|
|
} |
|
|
|
|
if (!notDetectedStrs.isEmpty()) { |
|
|
|
|
data.put("notDetectedStrs", "阴性结果:" + "\n" + notDetectedStrs.stream() |
|
|
|
|
.map(item -> "\u3000\u3000" + item) |
|
|
|
|
.collect(Collectors.joining("\u2611"))); |
|
|
|
|
.collect(Collectors.joining("\n"))); |
|
|
|
|
} |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
} |
|
|
|
@ -556,7 +559,8 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
System.out.println(data); |
|
|
|
|
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); |
|
|
|
|
Configure config = Configure.builder(). |
|
|
|
|
bind("dataDtos", policy).build(); |
|
|
|
|
bind("dataDtos", policy) |
|
|
|
|
.bind("ionPairAndCEVOS", policy).build(); |
|
|
|
|
return buildDocFileAndUploadToOss(entrustInfo.getId(), templatePath, config, data); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -579,25 +583,51 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
|
|
|
|
|
XWPFTemplate template = XWPFTemplate.compile(bis, config).render(data); |
|
|
|
|
NiceXWPFDocument document = template.getXWPFDocument(); |
|
|
|
|
|
|
|
|
|
List<XWPFTable> tables = document.getTables(); |
|
|
|
|
XWPFTable table = tables.get(tables.size() - 1); // 获取最后一个表格
|
|
|
|
|
|
|
|
|
|
int sampleSize = (int) data.get("sampleSize"); |
|
|
|
|
|
|
|
|
|
// **处理合并单元格**
|
|
|
|
|
int startRow = 1; // 从第二行开始(索引从0开始,所以第二行是索引1)
|
|
|
|
|
int mergeStep = 4; // 每4行合并一次
|
|
|
|
|
String type = (String) data.get("type"); |
|
|
|
|
|
|
|
|
|
// 指定需要合并的列(注意索引从0开始)
|
|
|
|
|
int[] mergeColumns = {0, 1, 2, 3, 4, 9}; // 1、2、3、4、5、10列的索引分别是 0, 1, 2, 3, 4, 9
|
|
|
|
|
if (type.equals("inVitro")) { |
|
|
|
|
int startRow = 1; // 从第二行开始(表头是第一行,索引从0开始)
|
|
|
|
|
// **处理合并单元格**
|
|
|
|
|
int mergeStep = 4; // 每4行合并一次
|
|
|
|
|
int[] mergeColumns = {0, 1, 2, 3, 4, 9}; // 合并的列:第1、2、3、4、5、10列,索引分别是 0, 1, 2, 3, 4, 9
|
|
|
|
|
|
|
|
|
|
// 遍历表格数据行
|
|
|
|
|
for (int rowIndex = startRow; rowIndex < table.getNumberOfRows(); rowIndex += mergeStep) { |
|
|
|
|
int endRow = Math.min(rowIndex + mergeStep - 1, table.getNumberOfRows() - 1); // 计算合并的终止行,防止越界
|
|
|
|
|
// 遍历表格数据行
|
|
|
|
|
for (int rowIndex = startRow; rowIndex < table.getNumberOfRows(); rowIndex += mergeStep) { |
|
|
|
|
int endRow = Math.min(rowIndex + mergeStep - 1, table.getNumberOfRows() - 1); // 计算合并的终止行,防止越界
|
|
|
|
|
for (int col : mergeColumns) { |
|
|
|
|
TableTools.mergeCellsVertically(table, col, rowIndex, endRow); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
int compoundSize = (int) data.get("compoundSize"); // 获取compoundSize值
|
|
|
|
|
|
|
|
|
|
// **处理合并单元格**
|
|
|
|
|
int startRow = 1; // 从第二行开始(表头是第一行,索引从0开始)
|
|
|
|
|
String currentCompoundName = null; |
|
|
|
|
int mergeStartRow = -1; |
|
|
|
|
|
|
|
|
|
for (int rowIndex = startRow; rowIndex < table.getNumberOfRows(); rowIndex++) { |
|
|
|
|
XWPFTableRow row = table.getRow(rowIndex); |
|
|
|
|
XWPFTableCell cell = row.getCell(1); // 获取第二列的单元格(索引1)
|
|
|
|
|
String compoundName = cell.getText().trim(); |
|
|
|
|
|
|
|
|
|
if (currentCompoundName == null || !currentCompoundName.equals(compoundName)) { |
|
|
|
|
// 如果当前化合物名称与上一行不同,则结束之前的合并
|
|
|
|
|
if (mergeStartRow >= 0 && rowIndex > mergeStartRow + 1) { |
|
|
|
|
TableTools.mergeCellsVertically(table, 1, mergeStartRow, rowIndex - 1); // 合并第二列(列索引1)
|
|
|
|
|
} |
|
|
|
|
currentCompoundName = compoundName; |
|
|
|
|
mergeStartRow = rowIndex; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (int col : mergeColumns) { |
|
|
|
|
TableTools.mergeCellsVertically(table, col, rowIndex, endRow); |
|
|
|
|
// 处理最后一组合并(循环结束后可能残留未合并的区域)
|
|
|
|
|
if (mergeStartRow >= 0 && mergeStartRow < table.getNumberOfRows() - 1) { |
|
|
|
|
TableTools.mergeCellsVertically(table, 1, mergeStartRow, table.getNumberOfRows() - 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -615,7 +645,6 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 生成常规毒品的检验记录(贵阳禁毒) |
|
|
|
|
*/ |
|
|
|
@ -720,13 +749,18 @@ public class InspectRecordServiceImpl implements InspectRecordService { |
|
|
|
|
if (references == null || references.isEmpty()) { |
|
|
|
|
data.put("referenceMaterialName", "未找到试剂耗材数据!"); |
|
|
|
|
} else { |
|
|
|
|
String firstStr = "\u2611" + " " + references.get(0).getReagentConsumableName() + "\n"; |
|
|
|
|
references.remove(references.get(0)); |
|
|
|
|
String referenceMaterialName = references.stream() |
|
|
|
|
.map(reagent -> "\u3000\u3000\u2611" + " " + reagent.getReagentConsumableName()) |
|
|
|
|
.collect(Collectors.joining("\n")); |
|
|
|
|
|
|
|
|
|
data.put("referenceMaterialName", firstStr + referenceMaterialName); |
|
|
|
|
String referenceMaterialName = ""; |
|
|
|
|
if (references.size() == 1) { |
|
|
|
|
referenceMaterialName = "\u2611" + " " + references.get(0).getReagentConsumableName(); |
|
|
|
|
} else { |
|
|
|
|
String firstStr = "\u2611" + " " + references.get(0).getReagentConsumableName() + "\n"; |
|
|
|
|
references.remove(references.get(0)); |
|
|
|
|
referenceMaterialName = firstStr + references.stream() |
|
|
|
|
.map(reagent -> "\u3000\u3000\u2611" + " " + reagent.getReagentConsumableName()) |
|
|
|
|
.collect(Collectors.joining("\n")); |
|
|
|
|
} |
|
|
|
|
data.put("referenceMaterialName", referenceMaterialName); |
|
|
|
|
|
|
|
|
|
data.put("materialIngredient", references.stream() |
|
|
|
|
.map(reagent -> reagent.getReagentConsumableName()) |
|
|
|
|