20250318 更新

1.分别提取实验图谱、生成检验记录的相关代码为独立的实现类
master
陈江保 2 weeks ago
parent cadaa7595c
commit 7852b2ccca
  1. 18
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordController.java
  2. 20
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/InspectRecordService.java
  3. 52
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestAtlasService.java
  4. 44
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordService.java
  5. 360
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/InspectRecordServiceImpl.java
  6. 252
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestAtlasServiceImpl.java
  7. 484
      dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordServiceImpl.java

@ -11,6 +11,8 @@ import digital.laboratory.platform.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.inspection.dto.DeleteTestAtlasDTO;
import digital.laboratory.platform.inspection.dto.TestRecordDto;
import digital.laboratory.platform.inspection.service.InspectRecordService;
import digital.laboratory.platform.inspection.service.TestAtlasService;
import digital.laboratory.platform.inspetion.api.entity.TestRecord;
import digital.laboratory.platform.inspection.service.TestRecordService;
import digital.laboratory.platform.inspection.vo.ProcedureVo;
@ -49,6 +51,12 @@ public class TestRecordController {
@Resource
private TestRecordService testRecordService;
@Resource
private InspectRecordService inspectRecordService;
@Resource
private TestAtlasService testAtlasService;
@Resource
private OssFile ossFile;
@ -139,7 +147,7 @@ public class TestRecordController {
public R uploadTestAtlas(@RequestParam("testId") String testId, @RequestPart("file") MultipartFile file) {
// ? R.ok("上传实验图谱成功!") : R.failed("上传实验图谱删除失败!")
try {
return testRecordService.uploadTestAtlas(testId, file);
return testAtlasService.uploadTestAtlas(testId, file);
} catch (Exception e) {
e.printStackTrace();
return R.failed("系统出错,请联系管理员!");
@ -150,7 +158,7 @@ public class TestRecordController {
@ApiOperation(value = "获取图谱列表")
@ApiImplicitParam(name = "testId", value = "该实验图谱关联的实验id")
public R getTestAtlasList(@RequestParam("testId") String testId) {
return testRecordService.getTestAtlasList(testId);
return testAtlasService.getTestAtlasList(testId);
}
@GetMapping("/getTestAtlasListByBusinessId")
@ -158,7 +166,7 @@ public class TestRecordController {
@ApiImplicitParam(name = "businessId", value = "该实验图谱关联的实验id")
public R getTestAtlasListByBusinessId(@RequestParam("businessId") String businessId) {
try {
return testRecordService.getTestAtlasListByBusinessId(businessId);
return testAtlasService.getTestAtlasListByBusinessId(businessId);
} catch (Exception e) {
e.printStackTrace();
return R.failed("系统出错,请联系管理员!");
@ -169,7 +177,7 @@ public class TestRecordController {
@ApiOperation(value = "删除图谱,支持批量删除")
public R deleteTestAtlas(@RequestBody @Valid DeleteTestAtlasDTO dto) {
try {
return testRecordService.deleteTestAtlas(dto);
return testAtlasService.deleteTestAtlas(dto);
} catch (Exception e) {
e.printStackTrace();
return R.failed(e.getMessage());
@ -215,7 +223,7 @@ public class TestRecordController {
@ApiOperation("生成检验记录-贵阳禁毒")
@GetMapping("/inspectionRecord")
public R inspectionRecord(String entrustId, String materialType) throws Exception {
return testRecordService.inspectionRecord(entrustId, materialType);
return inspectRecordService.inspectionRecord(entrustId, materialType);
}
}

@ -0,0 +1,20 @@
package digital.laboratory.platform.inspection.service;
import digital.laboratory.platform.common.core.util.R;
/**
* @author ChenJiangBao
* @version 1.0
* @description: 生成检验记录相关接口
* @date 2025/3/18 14:50
*/
public interface InspectRecordService {
/**
* 生成检验记录-贵阳禁毒
* @param entrustId 委托id
* @return
* @throws Exception
*/
R inspectionRecord(String entrustId, String materialType) throws Exception;
}

@ -0,0 +1,52 @@
package digital.laboratory.platform.inspection.service;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.inspection.dto.DeleteTestAtlasDTO;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* @author ChenJiangBao
* @version 1.0
* @description: 实验图谱相关接口
* @date 2025/3/18 14:56
*/
public interface TestAtlasService {
/**
* 上传实验图谱单个
* @param testId
* @param file
* @return
*/
R uploadTestAtlas(String testId, MultipartFile file) throws Exception;
/**
* 上传实验图谱(批量)
* @param testId
* @param files
* @return
*/
R uploadTestAtlasBatch(String testId, List<MultipartFile> files);
/**
* 获取该实验id的实验图谱
* @param testId
* @return
*/
R getTestAtlasList(String testId);
/**
* 删除实验图谱
* @param dto
* @return
*/
R deleteTestAtlas(DeleteTestAtlasDTO dto) throws Exception;
/**
* 根据业务id获取实验图谱
* @param businessId
* @return
*/
R getTestAtlasListByBusinessId(String businessId);
}

@ -47,42 +47,6 @@ public interface TestRecordService extends IService<TestRecord> {
Page<String> getResultSolutionPage(Page page, String testId);
/**
* 上传实验图谱单个
* @param testId
* @param file
* @return
*/
R uploadTestAtlas(String testId, MultipartFile file) throws Exception;
/**
* 上传实验图谱(批量)
* @param testId
* @param files
* @return
*/
R uploadTestAtlasBatch(String testId, List<MultipartFile> files);
/**
* 获取该实验id的实验图谱
* @param testId
* @return
*/
R getTestAtlasList(String testId);
/**
* 删除实验图谱
* @param dto
* @return
*/
R deleteTestAtlas(DeleteTestAtlasDTO dto) throws Exception;
/**
* 根据业务id获取实验图谱
* @param businessId
* @return
*/
R getTestAtlasListByBusinessId(String businessId);
/**
* 根据业务id获取实验信息
@ -91,14 +55,6 @@ public interface TestRecordService extends IService<TestRecord> {
*/
R<Map<String, TestRecordVo>> queryTestRecordInfoByBusinessId(List<String> businessIds);
/**
* 生成检验记录-贵阳禁毒
* @param entrustId 委托id
* @return
* @throws Exception
*/
R inspectionRecord(String entrustId, String materialType) throws Exception;
/**
* 根据业务id获取实验检验记录
* @param businessId

@ -0,0 +1,360 @@
package digital.laboratory.platform.inspection.service.impl;
import cn.hutool.core.util.StrUtil;
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;
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.constant.BusinessType;
import digital.laboratory.platform.inspection.constant.TestRecordFileUrl;
import digital.laboratory.platform.inspection.dto.HairSewageDataDto;
import digital.laboratory.platform.inspection.dto.NPSCaseTestDataDto;
import digital.laboratory.platform.inspection.entity.TestRecordInstrument;
import digital.laboratory.platform.inspection.entity.TestRecordReagent;
import digital.laboratory.platform.inspection.service.*;
import digital.laboratory.platform.inspetion.api.entity.EntrustInfo;
import digital.laboratory.platform.inspetion.api.entity.SampleInfo;
import digital.laboratory.platform.inspetion.api.entity.TestRecord;
import org.apache.commons.io.output.ByteArrayOutputStream;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author ChenJiangBao
* @version 1.0
* @description: 生成检验记录相关接口实现类
* @date 2025/3/18 14:50
*/
public class InspectRecordServiceImpl implements InspectRecordService {
@Resource
private OssFile ossFile;
@Resource
private EntrustInfoService entrustInfoService;
@Resource
private TestRecordService testRecordService;
@Resource
private TestRecordInstrumentService testRecordInstrumentService;
@Resource
private TestRecordSampleDataService testRecordSampleDataService;
@Resource
private TestRecordReagentService testRecordReagentService;
@Resource
private SampleInfoService sampleInfoService;
/**
* 生成检验记录-贵阳禁毒
*
* @param entrustId 委托id
* @param materialType 标注当前委托的检材是尿液还是毛发
* @return
* @throws Exception
*/
@Override
public R inspectionRecord(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), "生成成功!");
}
return null;
}
/**
* 生成生物样本检验记录数据map
* @param entrustInfo 委托实体信息
* @param materialType 检材类型
* @return
* @throws Exception
*/
public Map<String, Object> invivoRecord(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()
: testRecordInstrumentService.list(Wrappers.<TestRecordInstrument>lambdaQuery()
.in(TestRecordInstrument::getId, deviceIdList));
data.put("instrumentName", CollectionUtils.isEmpty(instruments)
? "未找到仪器设备数据!"
: instruments.stream()
.map(TestRecordInstrument::getInstrumentName)
.collect(Collectors.joining("\n"))
);
// 获取样品检测数据
List<HairSewageDataDto> hairDataDtos = (List<HairSewageDataDto>) testRecordSampleDataService
.getSampleTestDataByBusiness(entrustInfo.getId());
if (CollectionUtils.isEmpty(hairDataDtos)) {
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));
List<HairSewageDataDto> dataDtos = new ArrayList<>();
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;
}
return false;
});
// 排序
list.sort(this.getSortBySampleNo("inVivo"));
// 重新命名样品
if (list.size() == 1) {
list.get(0).setSampleName("检材样品");
} else {
for (int i = 0; i < list.size(); i++) {
list.get(i).setSampleName((i + 1) + "号检材样品");
}
}
dataDtos.addAll(list);
});
data.put("dataDtos", dataDtos);
data.put("sampleSize", dataDtos.size());
return data;
}
/**
* 根据委托信息和样本类型生成生物样本检验记录文件
*
* @param entrustInfo 委托信息对象
* @param materialType 样本类型"毛发""尿液"
* @return 生成的生物样本检验记录文件的路径
* @throws Exception 如果文件生成过程中出现错误抛出异常
*/
public String createInVivoFile(EntrustInfo entrustInfo, String materialType) throws Exception {
// 获取文件数据map
Map<String, Object> data = this.invivoRecord(entrustInfo, materialType);
// 调用模板生成检验记录
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String templatePath = "";
if (materialType.equals("毛发")) {
templatePath = "/template" + "/贵阳生物样本毛发检验记录模板.docx";
} else {
templatePath = "/template" + "/贵阳生物样本尿液检验记录模板.docx";
}
ossFile.fileGet(templatePath, bos);
byte[] templateArray = bos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(templateArray);
bos.close();
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
Configure config = Configure.builder().
bind("dataDtos", policy).build();
XWPFTemplate template = XWPFTemplate.compile(bis, config).render(
new HashMap<String, Object>() {{
put("entrustDepartment", data.get("entrustDepartment"));
put("deliver1Name", data.get("deliver1Name"));
put("deliver2Name", data.get("deliver2Name"));
put("year", data.get("year"));
put("month", data.get("month"));
put("day", data.get("day"));
put("instrumentName", data.get("instrumentName"));
put("referenceMaterialName", data.get("referenceMaterialName"));
put("reagentConsumableName", data.get("reagentConsumableName"));
put("dataDtos", data.get("dataDtos"));
}}
);
NiceXWPFDocument document = template.getXWPFDocument();
// XWPFTable table = document.getTables().get(3);
// int sampleSize = (int) data.get("sampleSize");
// //合并单元格
//
// TableTools.mergeCellsVertically(table, 1, 1, sampleSize);
bis.close();
ByteArrayOutputStream fosWord = new ByteArrayOutputStream();
template.write(fosWord);
template.close();
ByteArrayInputStream fisWord = new ByteArrayInputStream(fosWord.toByteArray());
fosWord.close();
document.close();
String path = TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + entrustInfo.getId() + "/" + "贵阳生物样本检验记录.docx";
ossFile.fileSave(path, fisWord);
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;
}
}
/**
* 生成常规毒品的检验记录贵阳禁毒
*/
public void generateCommonDrugInpectRecord(String entrustId) {
Map<String, Object> docMap = buildCommonDrugDocMap(entrustId);
}
/**
* 构建常规毒品的检验记录数据
*
* @return
*/
private Map<String, Object> buildCommonDrugDocMap(String entrustId) {
EntrustInfo entrustInfo = entrustInfoService.getById(entrustId);
// 这里因为检验记录实体并未关联业务id, 只能先查询实验数据,在通过实验数据获取到检验记录信息
TestRecord testRecord = testRecordService.getTestRecordByBusinessId(entrustInfo.getId());
// 封装数据到map中
Map<String, Object> docMap = buildCommonInspectRecordDocMap(entrustInfo, testRecord, "");
return docMap;
}
/**
* 构建通用的检验记录文档映射
*
* @param entrustInfo 委托信息对象
* @param materialType
* @return 包含委托信息和检验记录信息的HashMap对象
*/
private HashMap<String, Object> buildCommonInspectRecordDocMap(EntrustInfo entrustInfo, TestRecord testRecord, String materialType) {
HashMap<String, Object> data = new HashMap<>();
data.put("entrustDepartment", entrustInfo.getEntrustDepartment());
data.put("deliver1Name", entrustInfo.getDeliver1Name());
data.put("deliver2Name", entrustInfo.getDeliver2Name());
// 受理日期
data.put("acceptYear", entrustInfo.getAcceptDate().getYear());
data.put("acceptMonth", entrustInfo.getAcceptDate().getMonthValue());
data.put("acceptDay", entrustInfo.getAcceptDate().getDayOfMonth());
// 检验日期
data.put("inspectYear", testRecord.getTestStartDate().getYear());
data.put("inspectMonth", testRecord.getTestStartDate().getMonthValue());
data.put("inspectDay", testRecord.getTestStartDate().getDayOfMonth());
// 检材性状描述和检验要求成分
List<SampleInfo> sampleInfoList = sampleInfoService.list(Wrappers.<SampleInfo>lambdaQuery().eq(SampleInfo::getBusinessId, entrustInfo.getId()));
// 对检材进行筛选,如果materialType 不为空则进行操作
if (StrUtil.isNotBlank(materialType)) {
}
// buildMaterialCharacterDesc()
// 设置使用的标准物质和试剂
List<TestRecordReagent> references = testRecordReagentService.list(Wrappers.<TestRecordReagent>lambdaQuery()
.in(TestRecordReagent::getId, testRecord.getReagentConsumablesList())
.eq(TestRecordReagent::getCategory, "标准物质"));
if (references == null || references.size() == 0) {
data.put("referenceMaterialName", "未找到试剂耗材数据!");
} else {
String referenceMaterialName = references.stream()
.map(reagent -> "\u2611" + " " + reagent.getReagentConsumableName())
.collect(Collectors.joining("\n"));
data.put("referenceMaterialName", referenceMaterialName);
}
List<TestRecordReagent> reagents = testRecordReagentService.list(Wrappers.<TestRecordReagent>lambdaQuery()
.in(TestRecordReagent::getId, testRecord.getReagentConsumablesList())
.eq(TestRecordReagent::getCategory, "试剂"));
if (reagents == null || reagents.size() == 0) {
data.put("reagentConsumableName", "未找到试剂耗材数据!");
} else {
String reagentConsumableName = reagents.stream()
.map(TestRecordReagent::getReagentConsumableName)
.collect(Collectors.joining("、"));
data.put("reagentConsumableName", reagentConsumableName);
}
return data;
}
}

@ -0,0 +1,252 @@
package digital.laboratory.platform.inspection.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.inspection.constant.TestRecordFileUrl;
import digital.laboratory.platform.inspection.dto.DataSolutionSampleDTO;
import digital.laboratory.platform.inspection.dto.DeleteTestAtlasDTO;
import digital.laboratory.platform.inspection.mapper.TestRecordSampleDataMapper;
import digital.laboratory.platform.inspection.service.TestAtlasService;
import digital.laboratory.platform.inspection.service.TestRecordService;
import digital.laboratory.platform.inspetion.api.entity.TestRecord;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author ChenJiangBao
* @version 1.0
* @description: 实验图谱相关接口 相关实现类
* @date 2025/3/18 14:57
*/
public class TestAtlasServiceImpl implements TestAtlasService {
@Resource
private OssFile ossFile;
@Resource
private TestRecordService testRecordService;
@Resource
private TestRecordSampleDataMapper testRecordSampleDataMapper;
/**
* 上传实验图谱
*
* @param testId
* @param file
* @return
*/
@Override
public R uploadTestAtlas(String testId, MultipartFile file) throws Exception {
TestRecord testRecord = testRecordService.getById(testId);
if (testRecord == null) {
throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", testId));
}
// 取已上传过的实验图谱
JSONArray testAtlas = StrUtil.isBlank(testRecord.getTestAtlas()) ? new JSONArray() : JSONArray.parseArray(testRecord.getTestAtlas());
// 获取文件名list
List<String> fileNameList = new ArrayList<>();
for (int i = 0; i < testAtlas.size(); i++) {
JSONObject jsonObject = testAtlas.getJSONObject(i);
fileNameList.add(jsonObject.getString("fileName"));
}
// 拼接上传的路径,以实验id为文件夹
String commonPath = TestRecordFileUrl.TEST_ATLAS_PATH.getFileUrl() + testRecord.getId();
// 生成一个文件id
String fileId = IdWorker.getIdStr();
boolean upload = ossFile.fileUpload(file, commonPath);
String fileName = FileNameUtil.getName(file.getOriginalFilename());
String type = file.getContentType();
if (!upload) {
// 上传失败
Map<String, String> resultData = new HashMap<>();
resultData.put("fileName", fileName);
resultData.put("path", commonPath);
return R.failed(resultData, "上传实验图谱失败");
}
// if (testAtlas.size() > 0) {
// // 删除之前上传的
// JSONObject oldObject = testAtlas.getJSONObject(0);
// ossFile.fileDelete(oldObject.getString("path"));
// testAtlas = new JSONArray();
// }
JSONObject jsonObject = new JSONObject();
jsonObject.put("fileId", fileId);
jsonObject.put("fileName", fileName);
jsonObject.put("type", type);
jsonObject.put("path", commonPath + "/" + fileName);
testAtlas.add(jsonObject);
testRecord.setTestAtlas(testAtlas.toJSONString());
if (testRecordService.updateById(testRecord)) {
return R.ok("上传实验图谱成功!");
} else {
return R.failed("上传实验图谱失败!");
}
}
/**
* 上传实验图谱
*
* @param testId
* @param files
* @return
*/
@Override
public R uploadTestAtlasBatch(String testId, List<MultipartFile> files) {
TestRecord testRecord = testRecordService.getById(testId);
if (testRecord == null) {
throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", testId));
}
// 取已上传过的实验图谱
JSONArray testAtlas = StrUtil.isBlank(testRecord.getTestAtlas()) ? new JSONArray() : JSONArray.parseArray(testRecord.getTestAtlas());
// 获取文件名list
List<String> fileNameList = new ArrayList<>();
for (int i = 0; i < testAtlas.size(); i++) {
JSONObject jsonObject = testAtlas.getJSONObject(i);
fileNameList.add(jsonObject.getString("fileName"));
}
// 拼接上传的路径,以实验id为文件夹
String commonPath = TestRecordFileUrl.TEST_ATLAS_PATH.getFileUrl() + testRecord.getId();
// 这里遍历要上传的文件
for (MultipartFile file : files) {
// 获取id来防止因为文件名重复导致的问题
String fileId = IdWorker.getIdStr();
/*String filePath = commonPath + "/" + fileId + "/";*/
boolean upload = ossFile.fileUpload(file, commonPath);
String fileName = FileNameUtil.getName(file.getOriginalFilename());
String type = file.getContentType();
if (!upload) {
// 上传失败
Map<String, String> resultData = new HashMap<>();
resultData.put("fileName", fileName);
resultData.put("path", commonPath);
return R.failed(resultData, "上传实验图谱删除失败");
}
if (fileNameList.contains(fileName)) {
// 文件名存在则不用在添加一个json对象
continue;
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("fileId", fileId);
jsonObject.put("fileName", fileName);
jsonObject.put("type", type);
jsonObject.put("path", commonPath + "/" + fileName);
testAtlas.add(jsonObject);
}
testRecord.setTestAtlas(testAtlas.toJSONString());
if (testRecordService.updateById(testRecord)) {
return R.ok("上传实验图谱成功!");
} else {
return R.failed("上传实验图谱失败!");
}
}
/**
* 获取该实验id的实验图谱
*
* @param testId
* @return
*/
@Override
public R getTestAtlasList(String testId) {
TestRecord testRecord = testRecordService.getById(testId);
if (testRecord == null) {
throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", testId));
}
if (StrUtil.isBlank(testRecord.getTestAtlas())) {
return R.ok();
}
return R.ok(JSONArray.parseArray(testRecord.getTestAtlas()), "获取实验图谱列表成功!");
}
/**
* 删除实验图谱
*
* @param dto
* @return
*/
@Override
public R deleteTestAtlas(DeleteTestAtlasDTO dto) throws Exception {
TestRecord testRecord = testRecordService.getById(dto.getTestId());
if (testRecord == null) {
throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", dto.getTestId()));
}
JSONArray array = JSONArray.parseArray(testRecord.getTestAtlas());
if (CollUtil.isEmpty(array)) {
throw new RuntimeException("该实验的图谱为空!");
}
// 获取删除的fileid
List<String> fileIds = dto.getFileIds();
JSONArray newArray = new JSONArray();
int size = array.size();
for (int i = 0; i < size; i++) {
JSONObject jsonObject = array.getJSONObject(i);
String fileId = jsonObject.getString("fileId");
if (fileIds.contains(fileId)) {
ossFile.fileDelete(jsonObject.getString("path"));
} else {
// 不是删除的,就添加到新的数组
newArray.add(jsonObject);
}
}
// 更新
testRecord.setTestAtlas(newArray.toJSONString());
if (testRecordService.updateById(testRecord)) {
return R.ok(true, "实验图谱删除成功!");
} else {
return R.ok(false, "实验图谱删除失败!");
}
}
/**
* 根据业务id获取实验图谱
*
* @param businessId
* @return
*/
@Override
public R getTestAtlasListByBusinessId(String businessId) {
/**
* 先根据业务id 查询出检材id
*/
List<DataSolutionSampleDTO> testDataListByBusiness = testRecordSampleDataMapper
.queryDataSolutionSampleDTOList(Wrappers.<DataSolutionSampleDTO>query().eq("si.business_id", businessId));
if (CollUtil.isEmpty(testDataListByBusiness)) {
return R.ok();
}
// 2 根据查询出来的结果,取出实验id
List<String> testIdList = testDataListByBusiness.stream().map(DataSolutionSampleDTO::getTestId).collect(Collectors.toList());
// 3 根据实验id 获取实验信息
List<TestRecord> testRecordList = testRecordService.list(Wrappers.<TestRecord>lambdaQuery()
.in(TestRecord::getId, testIdList)
.orderByDesc(TestRecord::getUpdateTime));
// 最终返回的结果数组
JSONArray resultArray = new JSONArray();
for (TestRecord testRecord : testRecordList) {
if (StrUtil.isNotBlank(testRecord.getTestAtlas())) {
resultArray.addAll(JSONArray.parseArray(testRecord.getTestAtlas()));
}
}
return R.ok(resultArray, "根据业务id获取列表成功!");
}
}

@ -86,9 +86,9 @@ public class TestRecordServiceImpl extends ServiceImpl<TestRecordMapper, TestRec
@Resource
private TestRecordSampleDataService testRecordSampleDataService;
@Resource
private OssFile ossFile;
@Resource
private EntrustInfoService entrustInfoService;
@ -1302,211 +1302,6 @@ public class TestRecordServiceImpl extends ServiceImpl<TestRecordMapper, TestRec
return new PageUtils().getPages(page.getCurrent(), page.getSize(), list);
}
/**
* 上传实验图谱
*
* @param testId
* @param files
* @return
*/
@Override
public R uploadTestAtlas(String testId, MultipartFile file) throws Exception {
TestRecord testRecord = this.getById(testId);
if (testRecord == null) {
throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", testId));
}
// 取已上传过的实验图谱
JSONArray testAtlas = StrUtil.isBlank(testRecord.getTestAtlas()) ? new JSONArray() : JSONArray.parseArray(testRecord.getTestAtlas());
// 获取文件名list
List<String> fileNameList = new ArrayList<>();
for (int i = 0; i < testAtlas.size(); i++) {
JSONObject jsonObject = testAtlas.getJSONObject(i);
fileNameList.add(jsonObject.getString("fileName"));
}
// 拼接上传的路径,以实验id为文件夹
String commonPath = TestRecordFileUrl.TEST_ATLAS_PATH.getFileUrl() + testRecord.getId();
// 生成一个文件id
String fileId = IdWorker.getIdStr();
boolean upload = ossFile.fileUpload(file, commonPath);
String fileName = FileNameUtil.getName(file.getOriginalFilename());
String type = file.getContentType();
if (!upload) {
// 上传失败
Map<String, String> resultData = new HashMap<>();
resultData.put("fileName", fileName);
resultData.put("path", commonPath);
return R.failed(resultData, "上传实验图谱失败");
}
// if (testAtlas.size() > 0) {
// // 删除之前上传的
// JSONObject oldObject = testAtlas.getJSONObject(0);
// ossFile.fileDelete(oldObject.getString("path"));
// testAtlas = new JSONArray();
// }
JSONObject jsonObject = new JSONObject();
jsonObject.put("fileId", fileId);
jsonObject.put("fileName", fileName);
jsonObject.put("type", type);
jsonObject.put("path", commonPath + "/" + fileName);
testAtlas.add(jsonObject);
testRecord.setTestAtlas(testAtlas.toJSONString());
if (this.updateById(testRecord)) {
return R.ok("上传实验图谱成功!");
} else {
return R.failed("上传实验图谱失败!");
}
}
/**
* 上传实验图谱
*
* @param testId
* @param files
* @return
*/
@Override
public R uploadTestAtlasBatch(String testId, List<MultipartFile> files) {
TestRecord testRecord = this.getById(testId);
if (testRecord == null) {
throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", testId));
}
// 取已上传过的实验图谱
JSONArray testAtlas = StrUtil.isBlank(testRecord.getTestAtlas()) ? new JSONArray() : JSONArray.parseArray(testRecord.getTestAtlas());
// 获取文件名list
List<String> fileNameList = new ArrayList<>();
for (int i = 0; i < testAtlas.size(); i++) {
JSONObject jsonObject = testAtlas.getJSONObject(i);
fileNameList.add(jsonObject.getString("fileName"));
}
// 拼接上传的路径,以实验id为文件夹
String commonPath = TestRecordFileUrl.TEST_ATLAS_PATH.getFileUrl() + testRecord.getId();
// 这里遍历要上传的文件
for (MultipartFile file : files) {
// 获取id来防止因为文件名重复导致的问题
String fileId = IdWorker.getIdStr();
/*String filePath = commonPath + "/" + fileId + "/";*/
boolean upload = ossFile.fileUpload(file, commonPath);
String fileName = FileNameUtil.getName(file.getOriginalFilename());
String type = file.getContentType();
if (!upload) {
// 上传失败
Map<String, String> resultData = new HashMap<>();
resultData.put("fileName", fileName);
resultData.put("path", commonPath);
return R.failed(resultData, "上传实验图谱删除失败");
}
if (fileNameList.contains(fileName)) {
// 文件名存在则不用在添加一个json对象
continue;
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("fileId", fileId);
jsonObject.put("fileName", fileName);
jsonObject.put("type", type);
jsonObject.put("path", commonPath + "/" + fileName);
testAtlas.add(jsonObject);
}
testRecord.setTestAtlas(testAtlas.toJSONString());
if (this.updateById(testRecord)) {
return R.ok("上传实验图谱成功!");
} else {
return R.failed("上传实验图谱失败!");
}
}
/**
* 获取该实验id的实验图谱
*
* @param testId
* @return
*/
@Override
public R getTestAtlasList(String testId) {
TestRecord testRecord = this.getById(testId);
if (testRecord == null) {
throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", testId));
}
if (StrUtil.isBlank(testRecord.getTestAtlas())) {
return R.ok();
}
return R.ok(JSONArray.parseArray(testRecord.getTestAtlas()), "获取实验图谱列表成功!");
}
/**
* 删除实验图谱
*
* @param dto
* @return
*/
@Override
public R deleteTestAtlas(DeleteTestAtlasDTO dto) throws Exception {
TestRecord testRecord = this.getById(dto.getTestId());
if (testRecord == null) {
throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", dto.getTestId()));
}
JSONArray array = JSONArray.parseArray(testRecord.getTestAtlas());
if (CollUtil.isEmpty(array)) {
throw new RuntimeException("该实验的图谱为空!");
}
// 获取删除的fileid
List<String> fileIds = dto.getFileIds();
JSONArray newArray = new JSONArray();
int size = array.size();
for (int i = 0; i < size; i++) {
JSONObject jsonObject = array.getJSONObject(i);
String fileId = jsonObject.getString("fileId");
if (fileIds.contains(fileId)) {
ossFile.fileDelete(jsonObject.getString("path"));
} else {
// 不是删除的,就添加到新的数组
newArray.add(jsonObject);
}
}
// 更新
testRecord.setTestAtlas(newArray.toJSONString());
if (this.updateById(testRecord)) {
return R.ok(true, "实验图谱删除成功!");
} else {
return R.ok(false, "实验图谱删除失败!");
}
}
/**
* 根据业务id获取实验图谱
*
* @param businessId
* @return
*/
@Override
public R getTestAtlasListByBusinessId(String businessId) {
/**
* 先根据业务id 查询出检材id
*/
List<DataSolutionSampleDTO> testDataListByBusiness = testRecordSampleDataMapper
.queryDataSolutionSampleDTOList(Wrappers.<DataSolutionSampleDTO>query().eq("si.business_id", businessId));
if (CollUtil.isEmpty(testDataListByBusiness)) {
return R.ok();
}
// 2 根据查询出来的结果,取出实验id
List<String> testIdList = testDataListByBusiness.stream().map(DataSolutionSampleDTO::getTestId).collect(Collectors.toList());
// 3 根据实验id 获取实验信息
List<TestRecord> testRecordList = this.list(Wrappers.<TestRecord>lambdaQuery()
.in(TestRecord::getId, testIdList)
.orderByDesc(TestRecord::getUpdateTime));
// 最终返回的结果数组
JSONArray resultArray = new JSONArray();
for (TestRecord testRecord : testRecordList) {
if (StrUtil.isNotBlank(testRecord.getTestAtlas())) {
resultArray.addAll(JSONArray.parseArray(testRecord.getTestAtlas()));
}
}
return R.ok(resultArray, "根据业务id获取列表成功!");
}
/**
* 根据业务id获取实验信息
*
@ -1543,281 +1338,4 @@ public class TestRecordServiceImpl extends ServiceImpl<TestRecordMapper, TestRec
return R.ok(map);
}
/**
* 生成检验记录-贵阳禁毒
*
* @param entrustId 委托id
* @return
* @throws Exception
*/
@Override
public R inspectionRecord(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(map, entrustId, materialType), "生成成功!");
}
return null;
}
public Map<String, Object> invivoRecord(EntrustInfo entrustInfo) throws Exception {
// 获取检验记录信息
TestRecord testRecord = getTestRecordByBusinessId(entrustInfo.getId());
if (testRecord == null) {
throw new Exception("未找到检验记录信息");
}
HashMap<String, Object> data = buildCommonInspectRecordDocMap(entrustInfo, testRecord);
// 获取仪器设备数据
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(TestRecordInstrument::getInstrumentName)
.collect(Collectors.joining("\n"))
);
// 获取样品检测数据
List<HairSewageDataDto> hairDataDtos = (List<HairSewageDataDto>) testRecordSampleDataService
.getSampleTestDataByBusiness(entrustInfo.getId());
if (CollectionUtils.isEmpty(hairDataDtos)) {
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));
List<HairSewageDataDto> dataDtos = new ArrayList<>();
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;
}
return false;
});
// 排序
list.sort(this.getSortBySampleNo("inVivo"));
// 重新命名样品
if (list.size() == 1) {
list.get(0).setSampleName("检材样品");
} else {
for (int i = 0; i < list.size(); i++) {
list.get(i).setSampleName((i + 1) + "号检材样品");
}
}
dataDtos.addAll(list);
});
data.put("dataDtos", dataDtos);
data.put("sampleSize", dataDtos.size());
return data;
}
public String createInVivoFile(Map<String, Object> data, String entrustId, String materialType) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String templatePath = "";
if (materialType.equals("毛发")) {
templatePath = "/template" + "/贵阳生物样本毛发检验记录模板.docx";
} else {
templatePath = "/template" + "/贵阳生物样本尿液检验记录模板.docx";
}
ossFile.fileGet(templatePath, bos);
byte[] templateArray = bos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(templateArray);
bos.close();
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
Configure config = Configure.builder().
bind("dataDtos", policy).build();
XWPFTemplate template = XWPFTemplate.compile(bis, config).render(
new HashMap<String, Object>() {{
put("entrustDepartment", data.get("entrustDepartment"));
put("deliver1Name", data.get("deliver1Name"));
put("deliver2Name", data.get("deliver2Name"));
put("year", data.get("year"));
put("month", data.get("month"));
put("day", data.get("day"));
put("instrumentName", data.get("instrumentName"));
put("referenceMaterialName", data.get("referenceMaterialName"));
put("reagentConsumableName", data.get("reagentConsumableName"));
put("dataDtos", data.get("dataDtos"));
}}
);
NiceXWPFDocument document = template.getXWPFDocument();
// XWPFTable table = document.getTables().get(3);
// int sampleSize = (int) data.get("sampleSize");
// //合并单元格
//
// TableTools.mergeCellsVertically(table, 1, 1, sampleSize);
bis.close();
ByteArrayOutputStream fosWord = new ByteArrayOutputStream();
template.write(fosWord);
template.close();
ByteArrayInputStream fisWord = new ByteArrayInputStream(fosWord.toByteArray());
fosWord.close();
document.close();
String path = TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + entrustId + "/" + "贵阳生物样本检验记录.docx";
ossFile.fileSave(path, fisWord);
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;
}
}
/**
* 生成常规毒品的检验记录贵阳禁毒
*/
public void generateCommonDrugInpectRecord(String entrustId) {
Map<String, Object> docMap = buildCommonDrugDocMap(entrustId);
}
/**
* 构建常规毒品的检验记录数据
*
* @return
*/
private Map<String, Object> buildCommonDrugDocMap(String entrustId) {
EntrustInfo entrustInfo = entrustInfoService.getById(entrustId);
// 这里因为检验记录实体并未关联业务id, 只能先查询实验数据,在通过实验数据获取到检验记录信息
TestRecord testRecord = getTestRecordByBusinessId(entrustInfo.getId());
// 封装数据到map中
Map<String, Object> docMap = buildCommonInspectRecordDocMap(entrustInfo, testRecord);
return docMap;
}
/**
* 构建通用的检验记录文档映射
*
* @param entrustInfo 委托信息对象
* @return 包含委托信息和检验记录信息的HashMap对象
*/
private HashMap<String, Object> buildCommonInspectRecordDocMap(EntrustInfo entrustInfo, TestRecord testRecord) {
HashMap<String, Object> data = new HashMap<>();
data.put("entrustDepartment", entrustInfo.getEntrustDepartment());
data.put("deliver1Name", entrustInfo.getDeliver1Name());
data.put("deliver2Name", entrustInfo.getDeliver2Name());
// 受理日期
data.put("acceptYear", entrustInfo.getAcceptDate().getYear());
data.put("acceptMonth", entrustInfo.getAcceptDate().getMonthValue());
data.put("acceptDay", entrustInfo.getAcceptDate().getDayOfMonth());
// 检验日期
data.put("inspectYear", testRecord.getTestStartDate().getYear());
data.put("inspectMonth", testRecord.getTestStartDate().getMonthValue());
data.put("inspectDay", testRecord.getTestStartDate().getDayOfMonth());
// 检材性状描述和检验要求成分
// buildMaterialCharacterDesc()
// 设置使用的标准物质和试剂
List<TestRecordReagent> references = testRecordReagentService.list(Wrappers.<TestRecordReagent>lambdaQuery()
.in(TestRecordReagent::getId, testRecord.getReagentConsumablesList())
.eq(TestRecordReagent::getCategory, "标准物质"));
if (references == null || references.size() == 0) {
data.put("referenceMaterialName", "未找到试剂耗材数据!");
} else {
String referenceMaterialName = references.stream()
.map(reagent -> "\u2611" + " " + reagent.getReagentConsumableName())
.collect(Collectors.joining("\n"));
data.put("referenceMaterialName", referenceMaterialName);
}
List<TestRecordReagent> reagents = testRecordReagentService.list(Wrappers.<TestRecordReagent>lambdaQuery()
.in(TestRecordReagent::getId, testRecord.getReagentConsumablesList())
.eq(TestRecordReagent::getCategory, "试剂"));
if (reagents == null || reagents.size() == 0) {
data.put("reagentConsumableName", "未找到试剂耗材数据!");
} else {
String reagentConsumableName = reagents.stream()
.map(TestRecordReagent::getReagentConsumableName)
.collect(Collectors.joining("、"));
data.put("reagentConsumableName", reagentConsumableName);
}
return data;
}
}

Loading…
Cancel
Save