From 32794d079135d1dbbd2b92a182e42d301587192f Mon Sep 17 00:00:00 2001 From: wyb <1977763549@qq.com> Date: Wed, 12 Feb 2025 19:00:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E8=81=94=E4=BC=97=E9=87=87=E9=9B=86?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SyncBasicDataController.java | 26 +- .../docus/demo/dto/LianZhongUploadInfo.java | 108 +++++++++ .../demo/facade/ISyncBasicFileService.java | 3 + .../docus/demo/service/SyncBasicFileImpl.java | 223 +++++++++++++++++- src/main/resources/logback.xml | 22 +- .../resources/mapper/mysql/BasicMapper.xml | 4 +- 6 files changed, 356 insertions(+), 30 deletions(-) create mode 100644 src/main/java/com/docus/demo/dto/LianZhongUploadInfo.java diff --git a/src/main/java/com/docus/demo/controller/SyncBasicDataController.java b/src/main/java/com/docus/demo/controller/SyncBasicDataController.java index 7b4024c..1a2fbb6 100644 --- a/src/main/java/com/docus/demo/controller/SyncBasicDataController.java +++ b/src/main/java/com/docus/demo/controller/SyncBasicDataController.java @@ -2,6 +2,7 @@ package com.docus.demo.controller; import com.alibaba.fastjson.JSON; +import com.docus.demo.dto.LianZhongUploadInfo; import com.docus.demo.dto.SyncBasicDataDto; import com.docus.demo.dto.SyncFileDto; import com.docus.demo.dto.UploadJpgFileParam; @@ -23,7 +24,7 @@ import java.util.List; import java.util.concurrent.ConcurrentHashMap; @Api(value = "数据同步接口", tags = "数据同步接口") -@RestController("/sync") +@RestController @Slf4j public class SyncBasicDataController { @@ -175,6 +176,29 @@ public class SyncBasicDataController { } + /** + * @description: 文件上传 + * @params: files + * @params: uploadBatchFileParam + * @author linjj + * @date: 2024/6/28 10:38 + */ + @ApiOperation("标准版联众同步文件上传,相同名字的删除,不同的添加,用于个别单次无法上传完毕的") + @PostMapping(value = "/lianzhong/batchFileUploadJpg") + @ResponseBody + public CommonResult lianZhongBatchFileUploadJpg(@RequestPart("files") MultipartFile[] files, UploadJpgFileParam uploadJpgFileParam) { + try { + LianZhongUploadInfo lianZhongUploadInfo = JSON.parseObject(uploadJpgFileParam.getUploadFileParams(), LianZhongUploadInfo.class); + syncBasicFileService.lianZhongBatchFileUploadJpg(files, lianZhongUploadInfo); + return CommonResult.success("成功!"); + } catch (Exception e) { + log.error("联众同步文件上传,保存失败!异常处理" + e.getMessage(), e); + return CommonResult.failed("保存失败!异常处理" + e.getMessage()); + } + } + + + @ApiOperation("根据 病案号、姓名、出院日期、住院次数 进行筛选数据保留一条") diff --git a/src/main/java/com/docus/demo/dto/LianZhongUploadInfo.java b/src/main/java/com/docus/demo/dto/LianZhongUploadInfo.java new file mode 100644 index 0000000..b82b07f --- /dev/null +++ b/src/main/java/com/docus/demo/dto/LianZhongUploadInfo.java @@ -0,0 +1,108 @@ +package com.docus.demo.dto; + +import lombok.Data; + +import java.util.List; + +/** + * 联众上传信息 + */ +@Data +public class LianZhongUploadInfo { + /** + * + * 联众上传患者信息 + */ + @Data + public static class PatientInfo { + /** + * 病案号 + */ + private String inpatientNo; + /** + * 住院次数 + */ + private Integer admissTimes; + /** + * 姓名 + */ + private String name; + /** + * 性别 男1,女2 + */ + private String sex; + /** + * 性别,男女 + */ + private String sexName; + /** + * 年龄-岁 + */ + private Integer age; + /** + * 入院日期 yyyy-MM-dd HH:mm:ss + */ + private String admissDate; + /** + * 出院日期 yyyy-MM-dd HH:mm:ss + */ + private String disDate; + /** + * 入院科室编码 + */ + private String admissDeptName; + /** + * 出院科室名称 + */ + private String disDeptName; + /** + * 身份证号 + */ + private String idCard; + /** + * 主要诊断编码 + */ + private String mainDiagCode; + /** + * 主要诊断名称 + */ + private String mainDiagName; + /** + * 主要手术编码 + */ + private String mainOperateCode; + /** + * 主要手术名称 + */ + private String mainOperateName; + } + /** + * + * 联众上传文件信息 + */ + @Data + public static class FileInfo { + /** + * 文件分段id + */ + private String assortId; + + /** + * 文件展示标题 + */ + private String fileTitle; + + /** + * 上传的本地文件名 + */ + private String uploadFileName; + + /** + * 文件排序 + */ + private int sort; + } + + private PatientInfo patientInfo; + private List fileInfos; +} diff --git a/src/main/java/com/docus/demo/facade/ISyncBasicFileService.java b/src/main/java/com/docus/demo/facade/ISyncBasicFileService.java index 1878bcc..28d4df5 100644 --- a/src/main/java/com/docus/demo/facade/ISyncBasicFileService.java +++ b/src/main/java/com/docus/demo/facade/ISyncBasicFileService.java @@ -1,5 +1,6 @@ package com.docus.demo.facade; +import com.docus.demo.dto.LianZhongUploadInfo; import com.docus.demo.dto.SyncBasicDataDto; import com.docus.demo.dto.SyncFileDto; import com.docus.demo.dto.UploadJpgFileParam; @@ -22,4 +23,6 @@ public interface ISyncBasicFileService { CommonResultfileUploadJpg(MultipartFile[] files, UploadJpgFileParam uploadJpgFileParam); CommonResult batchFileUploadJpg(MultipartFile[] files, UploadJpgFileParam uploadJpgFileParam); + + void lianZhongBatchFileUploadJpg(MultipartFile[] files, LianZhongUploadInfo lianZhongUploadInfo); } diff --git a/src/main/java/com/docus/demo/service/SyncBasicFileImpl.java b/src/main/java/com/docus/demo/service/SyncBasicFileImpl.java index ac71085..0849dc4 100644 --- a/src/main/java/com/docus/demo/service/SyncBasicFileImpl.java +++ b/src/main/java/com/docus/demo/service/SyncBasicFileImpl.java @@ -2,8 +2,18 @@ package com.docus.demo.service; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONArray; -import com.docus.demo.dto.*; -import com.docus.demo.entity.*; +import com.docus.demo.dto.BasicSelectDto; +import com.docus.demo.dto.FileUploadJpgDto; +import com.docus.demo.dto.LianZhongUploadInfo; +import com.docus.demo.dto.SyncBasicDataDto; +import com.docus.demo.dto.SyncFileDto; +import com.docus.demo.dto.UploadJpgFileParam; +import com.docus.demo.entity.CommonResult; +import com.docus.demo.entity.ScanAssort; +import com.docus.demo.entity.TCardInfo; +import com.docus.demo.entity.TPicture; +import com.docus.demo.entity.Tbasic; +import com.docus.demo.entity.TbasicSub; import com.docus.demo.facade.BasicDeptService; import com.docus.demo.facade.ISyncBasicFileService; import com.docus.demo.mapper.mysql.BasicMapper; @@ -11,7 +21,6 @@ import com.docus.demo.mapper.mysql.ScanAssortMapper; import com.docus.demo.mapper.sqlserver.PictureMapper; import com.docus.demo.utils.SnowflakeIdWorker; import com.docus.demo.vo.BasicVo; - import com.github.xiaoymin.knife4j.core.util.StrUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -24,8 +33,16 @@ import javax.annotation.Resource; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; -import java.util.*; -import java.util.concurrent.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Slf4j @@ -407,6 +424,167 @@ public class SyncBasicFileImpl implements ISyncBasicFileService { return CommonResult.success("上传完成"); } + @Override + public void lianZhongBatchFileUploadJpg(MultipartFile[] files, LianZhongUploadInfo lianZhongUploadInfo) { + final String source = "lianzhong"; + + LianZhongUploadInfo.PatientInfo patientInfo = lianZhongUploadInfo.getPatientInfo(); + List fileInfos = lianZhongUploadInfo.getFileInfos(); + + //解析文件上传参数 + if (fileInfos.size() != files.length) { + throw new RuntimeException("文件上传数量与参数不一致!"); + } + // 参数不含上传的,不匹配 + List originalFileNames = fileInfos.stream().map(item -> String.valueOf(item.getUploadFileName())).collect(Collectors.toList()); + for (MultipartFile file : files) { + if (!originalFileNames.contains(file.getOriginalFilename())) { + throw new RuntimeException("文件名:" + file.getOriginalFilename() + "与病案号:" + patientInfo.getInpatientNo() + "集合中中文名不匹配"); + } + } + + Tbasic oldBasic = getOldTbasic(patientInfo); + Tbasic tbasic = oldBasic; + if (oldBasic == null) { + ArrayList tbasics = new ArrayList<>(); + //组织基础数据 + Tbasic addTbasic = getTbasic(patientInfo); + tbasics.add(addTbasic); + basicDeptService.handleDept(tbasics); + basicMapper.addBasic(tbasics); + tbasic = addTbasic; + } + + + // 删除旧的存在的同名的联众文件数据、图像 + if (oldBasic != null) { + List scanAssort = scanAssortMapper.getScanAssort(oldBasic.getPatientId(), source); + if (!CollectionUtils.isEmpty(scanAssort)) { + for (MultipartFile file : files) { + String originalFilename = file.getOriginalFilename(); + for (ScanAssort assort : scanAssort) { + if (originalFilename.equals(assort.getScanPage())) { + File oldFile = new File(assort.getImagePath() + File.separatorChar + assort.getScanPage()); + try { + oldFile.delete(); // 删除照片 + scanAssortMapper.delScanAssortById(assort.getId()); + break; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + } + } + + // 保存文件和文件数据 + String filePathdir = createDirectory(tbasic); + //保存文件 + ArrayList scanAssorts = new ArrayList<>(); + for (MultipartFile file : files) { + for (LianZhongUploadInfo.FileInfo fileInfo : fileInfos) { + //上传原文件名与实际文件名一致 + if (fileInfo.getUploadFileName().equals(file.getOriginalFilename())) { + //记录排序 + final int[] sort = {0}; + ScanAssort tScanAssortDto = addScanAssort(tbasic.getPatientId(), filePathdir, file, fileInfo); + if (Objects.isNull(tScanAssortDto)) { + log.info("批次病案主键:" + tbasic.getPatientId() + "中" + fileInfo.getFileTitle() + "中保存失败"); + } else { + tScanAssortDto.setSource(source); + scanAssorts.add(tScanAssortDto); + } + } + } + } + if (!scanAssortMapper.addScanAssort(scanAssorts)) { + throw new RuntimeException(tbasic.getPatientId() + "保存文件数据库失败"); + } + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + log.info("联众同步文件上传,本次批次传输成功病案号码为:{}({})" + tbasic.getInpatientNo(), sdf.format(tbasic.getDisDate())); + } + + private ScanAssort addScanAssort(String patientId, String filePathdir, MultipartFile file, LianZhongUploadInfo.FileInfo fileInfo) { + + //文件保存地址 + String toJpgFilePath = filePathdir + File.separatorChar + fileInfo.getUploadFileName(); + try { + file.transferTo(new File(toJpgFilePath)); + } catch (IOException e) { + log.error("将jpg文件保存本地失败:" + fileInfo.getUploadFileName() + "," + e.getMessage(), e); + return null; + } + //组织新数据 + ScanAssort scanAssort = new ScanAssort(); + scanAssort.setId(SnowflakeIdWorker.idWorker.nextId()); + scanAssort.setPatientId(patientId); + scanAssort.setAssortId(fileInfo.getAssortId()); + scanAssort.setFileTitle(fileInfo.getFileTitle()); + scanAssort.setImagePath(filePathdir); + scanAssort.setCreateTime(new Date()); + scanAssort.setScanPage(fileInfo.getUploadFileName()); + scanAssort.setSort(fileInfo.getSort()); + scanAssort.setFileSource(2); + scanAssort.setFileStorageType(1); + scanAssort.setFilePages(1); + scanAssort.setCreater("lianzhong-sync"); + return scanAssort; + } + + private String createDirectory(Tbasic tbasic) { + //根据年/月/日/住院号/patientId生成目录 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date disDate = tbasic.getDisDate(); + String inpatientNo = tbasic.getInpatientNo(); + String patientId = tbasic.getPatientId(); + String disDateTime = sdf.format(disDate); + String[] parts = disDateTime.split("-"); + String year = parts[0]; + String month = parts[1]; + String day = parts[2]; + //文件保存目录 + String filePathdir = savePath + + File.separatorChar + year + + File.separatorChar + month + + File.separatorChar + day + + File.separatorChar + inpatientNo + + File.separatorChar + inpatientNo + + patientId; + File filePath = new File(filePathdir); + //判断文件夹是否存在不存在创建文件夹 + if (!filePath.exists()) { + filePath.mkdirs(); + } + return filePathdir; + } + + + private Tbasic getOldTbasic(LianZhongUploadInfo.PatientInfo patientInfo) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String inpatientNo = patientInfo.getInpatientNo(); + Date disDate = sdf2.parse(patientInfo.getDisDate()); + String name = patientInfo.getName(); + + List inpatientNos = Collections.singletonList(inpatientNo); + SyncBasicDataDto dto = new SyncBasicDataDto(); + List oldBasicList = basicMapper.getOldBasicList(inpatientNos, dto); + for (Tbasic tbasic : oldBasicList) { + // 名字,病案号,出院日期 相同 ,认为是一个数据 + if (ObjectUtil.equals(tbasic.getName(), name) + && tbasic.getInpatientNo().equalsIgnoreCase(inpatientNo) + && sdf.format(disDate).equals(sdf.format(tbasic.getDisDate()))) { + return tbasic; + } + } + return null; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + private Tbasic getOldTbasic(FileUploadJpgDto fileUploadJpgDto) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // String admissId = fileUploadJpgDto.getAdmissId(); @@ -421,7 +599,6 @@ public class SyncBasicFileImpl implements ISyncBasicFileService { SyncBasicDataDto dto = new SyncBasicDataDto(); List oldBasicList = basicMapper.getOldBasicList(inpatientNos, dto); for (Tbasic tbasic : oldBasicList) { - // 名字,病案号,住院次数,出院时间 相同 ,人为是一个数据 if (ObjectUtil.equals(tbasic.getName(), fileUploadJpgDto.getName()) && tbasic.getInpatientNo().equalsIgnoreCase(jpgDtoInpatientNo) @@ -488,6 +665,40 @@ public class SyncBasicFileImpl implements ISyncBasicFileService { return scanAssort; } + private Tbasic getTbasic(LianZhongUploadInfo.PatientInfo patientInfo) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Tbasic addTbasic = new Tbasic(); + addTbasic.setPatientId(String.valueOf(SnowflakeIdWorker.idWorker.nextId())); + addTbasic.setAdmissTimes(patientInfo.getAdmissTimes()); + addTbasic.setInpatientNo(patientInfo.getInpatientNo()); + addTbasic.setName(patientInfo.getName()); + addTbasic.setSex(patientInfo.getSex()); + addTbasic.setSexName(patientInfo.getSexName()); + addTbasic.setAge(patientInfo.getAge()); + addTbasic.setIdCard(patientInfo.getIdCard()); + try { + addTbasic.setAdmissDate(cn.hutool.core.util.StrUtil.isBlank(patientInfo.getAdmissDate()) ? null : sdf.parse(patientInfo.getAdmissDate())); + addTbasic.setDisDate(sdf.parse(patientInfo.getDisDate())); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + addTbasic.setAdmissDeptName(patientInfo.getAdmissDeptName()); + addTbasic.setDisDeptName(patientInfo.getDisDeptName()); + addTbasic.setMainDiagName(patientInfo.getMainDiagName()); + addTbasic.setMainDiagCode(patientInfo.getMainDiagCode()); + addTbasic.setMainOperateName(patientInfo.getMainOperateName()); + addTbasic.setMainOperateCode(patientInfo.getMainOperateCode()); + addTbasic.setBColumn8(1); + addTbasic.setIsArchive(1); + addTbasic.setArchiveFileStorageType(2); + addTbasic.setCreateTime(new Date()); + addTbasic.setFileSource(3); + addTbasic.setScanSource("1"); + addTbasic.setScanUploadState(1); + return addTbasic; + } + + private Tbasic getTbasic(List fileUploadJpg) { FileUploadJpgDto fileUploadJpgDto = fileUploadJpg.get(0); Tbasic addTbasic = new Tbasic(); diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 2fcbe02..fad1f25 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -21,31 +21,11 @@ ${log.path}%d.%i.log - 500MB + 50MB 30 - - - - [%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%X{traceId}] [%L] [%-5p] %m%n - utf-8 - - - - - ${log.path}external%d.%i.log - - 500MB - - 30 - - - - - diff --git a/src/main/resources/mapper/mysql/BasicMapper.xml b/src/main/resources/mapper/mysql/BasicMapper.xml index 7832e34..8efc8dc 100644 --- a/src/main/resources/mapper/mysql/BasicMapper.xml +++ b/src/main/resources/mapper/mysql/BasicMapper.xml @@ -45,7 +45,7 @@ insert into docus_medicalrecord.t_basic (patient_id,admiss_times,inpatient_no,admiss_id, - name,sex_name,age,id_card, + name,sex,sex_name,age,id_card, admiss_date,admiss_dept,admiss_dept_name,dis_date, dis_dept,dis_dept_name,main_diag_code,main_diag_name, main_operate_code,main_operate_name,create_time,is_archive, @@ -55,7 +55,7 @@ values (#{item.patientId},#{item.admissTimes},#{item.inpatientNo},#{item.admissId}, - #{item.name},#{item.sex},#{item.age},#{item.idCard}, + #{item.name},#{item.sex},#{item.sexName},#{item.age},#{item.idCard}, #{item.admissDate},#{item.admissDept},#{item.admissDeptName},#{item.disDate}, #{item.disDept},#{item.disDeptName},#{item.mainDiagCode},#{item.mainDiagName}, #{item.mainOperateCode},#{item.mainOperateName},#{item.createTime},#{item.isArchive},