From 7852b2ccca25d99c36de4f55d70a51e8d84b0ad1 Mon Sep 17 00:00:00 2001 From: chen <2710907404@qq.com> Date: Tue, 18 Mar 2025 15:06:39 +0800 Subject: [PATCH] =?UTF-8?q?20250318=20=E6=9B=B4=E6=96=B0=201.=E5=88=86?= =?UTF-8?q?=E5=88=AB=E6=8F=90=E5=8F=96=E5=AE=9E=E9=AA=8C=E5=9B=BE=E8=B0=B1?= =?UTF-8?q?=E3=80=81=E7=94=9F=E6=88=90=E6=A3=80=E9=AA=8C=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E7=9A=84=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81=E4=B8=BA=E7=8B=AC?= =?UTF-8?q?=E7=AB=8B=E7=9A=84=E5=AE=9E=E7=8E=B0=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/TestRecordController.java | 18 +- .../service/InspectRecordService.java | 20 + .../inspection/service/TestAtlasService.java | 52 ++ .../inspection/service/TestRecordService.java | 44 -- .../impl/InspectRecordServiceImpl.java | 360 +++++++++++++ .../service/impl/TestAtlasServiceImpl.java | 252 +++++++++ .../service/impl/TestRecordServiceImpl.java | 484 +----------------- 7 files changed, 698 insertions(+), 532 deletions(-) create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/InspectRecordService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestAtlasService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/InspectRecordServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestAtlasServiceImpl.java diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordController.java index aeb0f82..c3e630b 100644 --- a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordController.java +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordController.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); } } diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/InspectRecordService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/InspectRecordService.java new file mode 100644 index 0000000..0f29e41 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/InspectRecordService.java @@ -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; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestAtlasService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestAtlasService.java new file mode 100644 index 0000000..b59f521 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestAtlasService.java @@ -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 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); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordService.java index 672d8f7..7422a16 100644 --- a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordService.java +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordService.java @@ -47,42 +47,6 @@ public interface TestRecordService extends IService { Page 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 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 { */ R> queryTestRecordInfoByBusinessId(List businessIds); - /** - * 生成检验记录-贵阳禁毒 - * @param entrustId 委托id - * @return - * @throws Exception - */ - R inspectionRecord(String entrustId, String materialType) throws Exception; - /** * 根据业务id获取实验检验记录 * @param businessId diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/InspectRecordServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/InspectRecordServiceImpl.java new file mode 100644 index 0000000..1c9590b --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/InspectRecordServiceImpl.java @@ -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 map = this.invivoRecord(entrustInfo); + return R.ok(this.createInVivoFile(entrustInfo, materialType), "生成成功!"); + } + return null; + } + + /** + * 生成生物样本检验记录数据map + * @param entrustInfo 委托实体信息 + * @param materialType 检材类型 + * @return + * @throws Exception + */ + public Map invivoRecord(EntrustInfo entrustInfo, String materialType) throws Exception { + // 获取检验记录信息 + TestRecord testRecord = testRecordService.getTestRecordByBusinessId(entrustInfo.getId()); + if (testRecord == null) { + throw new Exception("未找到检验记录信息"); + } + + HashMap data = buildCommonInspectRecordDocMap(entrustInfo, testRecord, materialType); + + // 获取仪器设备数据 + List deviceIdList = testRecord.getDeviceIdList(); + List instruments = CollectionUtils.isEmpty(deviceIdList) + ? Collections.emptyList() + : testRecordInstrumentService.list(Wrappers.lambdaQuery() + .in(TestRecordInstrument::getId, deviceIdList)); + + data.put("instrumentName", CollectionUtils.isEmpty(instruments) + ? "未找到仪器设备数据!" + : instruments.stream() + .map(TestRecordInstrument::getInstrumentName) + .collect(Collectors.joining("\n")) + ); + + // 获取样品检测数据 + List hairDataDtos = (List) testRecordSampleDataService + .getSampleTestDataByBusiness(entrustInfo.getId()); + + if (CollectionUtils.isEmpty(hairDataDtos)) { + data.put("dataDtos", Collections.emptyList()); + data.put("sampleSize", 0); + data.put("vo", testRecord); + return data; + } + + // 处理检测数据 + Map> dataMap = hairDataDtos.stream() + .collect(Collectors.groupingBy(HairSewageDataDto::getCompoundName)); + + List 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 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() {{ + 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 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 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 docMap = buildCommonDrugDocMap(entrustId); + } + + /** + * 构建常规毒品的检验记录数据 + * + * @return + */ + private Map buildCommonDrugDocMap(String entrustId) { + EntrustInfo entrustInfo = entrustInfoService.getById(entrustId); + + // 这里因为检验记录实体并未关联业务id, 只能先查询实验数据,在通过实验数据获取到检验记录信息 + TestRecord testRecord = testRecordService.getTestRecordByBusinessId(entrustInfo.getId()); + + // 封装数据到map中 + Map docMap = buildCommonInspectRecordDocMap(entrustInfo, testRecord, ""); + + return docMap; + } + + + /** + * 构建通用的检验记录文档映射 + * + * @param entrustInfo 委托信息对象 + * @param materialType + * @return 包含委托信息和检验记录信息的HashMap对象 + */ + private HashMap buildCommonInspectRecordDocMap(EntrustInfo entrustInfo, TestRecord testRecord, String materialType) { + HashMap 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 sampleInfoList = sampleInfoService.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, entrustInfo.getId())); + // 对检材进行筛选,如果materialType 不为空则进行操作 + if (StrUtil.isNotBlank(materialType)) { + + } +// buildMaterialCharacterDesc() + + // 设置使用的标准物质和试剂 + List references = testRecordReagentService.list(Wrappers.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 reagents = testRecordReagentService.list(Wrappers.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; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestAtlasServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestAtlasServiceImpl.java new file mode 100644 index 0000000..5bb613f --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestAtlasServiceImpl.java @@ -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 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 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 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 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 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 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 testDataListByBusiness = testRecordSampleDataMapper + .queryDataSolutionSampleDTOList(Wrappers.query().eq("si.business_id", businessId)); + if (CollUtil.isEmpty(testDataListByBusiness)) { + return R.ok(); + } + // 2 根据查询出来的结果,取出实验id + List testIdList = testDataListByBusiness.stream().map(DataSolutionSampleDTO::getTestId).collect(Collectors.toList()); + // 3 根据实验id 获取实验信息 + List testRecordList = testRecordService.list(Wrappers.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获取列表成功!"); + } + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordServiceImpl.java index d406502..b8b9416 100644 --- a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordServiceImpl.java +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordServiceImpl.java @@ -86,9 +86,9 @@ public class TestRecordServiceImpl extends ServiceImpl 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 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 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 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 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 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 testDataListByBusiness = testRecordSampleDataMapper - .queryDataSolutionSampleDTOList(Wrappers.query().eq("si.business_id", businessId)); - if (CollUtil.isEmpty(testDataListByBusiness)) { - return R.ok(); - } - // 2 根据查询出来的结果,取出实验id - List testIdList = testDataListByBusiness.stream().map(DataSolutionSampleDTO::getTestId).collect(Collectors.toList()); - // 3 根据实验id 获取实验信息 - List testRecordList = this.list(Wrappers.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 map = this.invivoRecord(entrustInfo); - return R.ok(this.createInVivoFile(map, entrustId, materialType), "生成成功!"); - } - return null; - } - - public Map invivoRecord(EntrustInfo entrustInfo) throws Exception { - // 获取检验记录信息 - TestRecord testRecord = getTestRecordByBusinessId(entrustInfo.getId()); - if (testRecord == null) { - throw new Exception("未找到检验记录信息"); - } - - HashMap data = buildCommonInspectRecordDocMap(entrustInfo, testRecord); - - // 获取仪器设备数据 - List deviceIdList = testRecord.getDeviceIdList(); - List instruments = CollectionUtils.isEmpty(deviceIdList) - ? Collections.emptyList() - : testRecordInstrumentService.list(Wrappers.lambdaQuery() - .in(TestRecordInstrument::getId, deviceIdList)); - - data.put("instrumentName", CollectionUtils.isEmpty(instruments) - ? "未找到仪器设备数据!" - : instruments.stream() - .map(TestRecordInstrument::getInstrumentName) - .collect(Collectors.joining("\n")) - ); - - // 获取样品检测数据 - List hairDataDtos = (List) testRecordSampleDataService - .getSampleTestDataByBusiness(entrustInfo.getId()); - - if (CollectionUtils.isEmpty(hairDataDtos)) { - data.put("dataDtos", Collections.emptyList()); - data.put("sampleSize", 0); - data.put("vo", testRecord); - return data; - } - - // 处理检测数据 - Map> dataMap = hairDataDtos.stream() - .collect(Collectors.groupingBy(HairSewageDataDto::getCompoundName)); - - List 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 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() {{ - 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 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 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 docMap = buildCommonDrugDocMap(entrustId); - } - - /** - * 构建常规毒品的检验记录数据 - * - * @return - */ - private Map buildCommonDrugDocMap(String entrustId) { - EntrustInfo entrustInfo = entrustInfoService.getById(entrustId); - - // 这里因为检验记录实体并未关联业务id, 只能先查询实验数据,在通过实验数据获取到检验记录信息 - TestRecord testRecord = getTestRecordByBusinessId(entrustInfo.getId()); - - // 封装数据到map中 - Map docMap = buildCommonInspectRecordDocMap(entrustInfo, testRecord); - - return docMap; - } - - - /** - * 构建通用的检验记录文档映射 - * - * @param entrustInfo 委托信息对象 - * @return 包含委托信息和检验记录信息的HashMap对象 - */ - private HashMap buildCommonInspectRecordDocMap(EntrustInfo entrustInfo, TestRecord testRecord) { - HashMap 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 references = testRecordReagentService.list(Wrappers.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 reagents = testRecordReagentService.list(Wrappers.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; - } }