parent
							
								
									cadaa7595c
								
							
						
					
					
						commit
						7852b2ccca
					
				@ -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); | 
				
			||||
} | 
				
			||||
@ -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获取列表成功!"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
 | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue