diff --git a/pom.xml b/pom.xml index b2b9061..492ea19 100644 --- a/pom.xml +++ b/pom.xml @@ -102,6 +102,25 @@ 2.8.6 + + + net.coobird + thumbnailator + 0.4.8 + + + com.twelvemonkeys.imageio + imageio-jpeg + 3.8.1 + + + + com.twelvemonkeys.imageio + imageio-tiff + 3.8.1 + + + diff --git a/src/main/java/com/jiashi/FilePathUtil.java b/src/main/java/com/jiashi/FilePathUtil.java new file mode 100644 index 0000000..d934868 --- /dev/null +++ b/src/main/java/com/jiashi/FilePathUtil.java @@ -0,0 +1,96 @@ +package com.jiashi; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.Objects; + +/** + * @author 文件路径工具 + */ +public class FilePathUtil { + private static final Logger logger = LoggerFactory.getLogger(FilePathUtil.class); + + /** + * 当前所在文件路径 + * + * @return 当前所在文件路径 + */ + + public static String currentPath() { + try { + File file = new File("."); + return file.getCanonicalPath(); + } catch (Exception ex) { + return null; + } + } + + /** + * 临时缓存文件夹 + * + * @return 临时缓存文件夹 + */ + public static String tempPath() { + String tempPath; + try { + tempPath = currentPath() + File.separator + "temp"; + } catch (Exception ex) { + tempPath = "C:\\docus\\temp"; + } + mkdirs(tempPath); + return tempPath; + } + + /** + * 根据文件夹路径创建文件目录 + * @param path 文件目录路径 + */ + public static void mkdirs(String path) { + path = Objects.requireNonNull(path); + mkdirs(new File(path)); + } + + /** + * 创建文件目录 + * @param file 文件目录 + */ + public static void mkdirs(File file) { + if (!file.exists()) { + if (!file.mkdirs()) { + // Not processed + logger.warn("mkdirs error : {}", file); + } + } + } + + + /** + * 递归删除目录下的所有文件及子目录下所有文件 + * @param dir 将要删除的文件目录 + */ + public static void deleteDir(File dir) { + if (dir.isDirectory()) { + String[] children = dir.list(); + if (children!=null) { + //递归删除目录中的子目录下 + for (String child : children) { + deleteDir(new File(dir, child)); + } + } + } + // 目录此时为空,可以删除 + dir.delete(); + } + + /** + * 递归删除目录下的所有文件及子目录下所有文件 + * @param dir 将要删除的文件目录路径 + */ + public static void deleteDir(String dir) { + deleteDir(new File(dir)); + } + + +} diff --git a/src/main/java/com/jiashi/FileUploader.java b/src/main/java/com/jiashi/FileUploader.java index a292392..0cdea26 100644 --- a/src/main/java/com/jiashi/FileUploader.java +++ b/src/main/java/com/jiashi/FileUploader.java @@ -6,7 +6,7 @@ import okhttp3.*; import java.io.File; import java.io.IOException; -import java.util.ArrayList; + import java.util.List; import java.util.concurrent.TimeUnit; diff --git a/src/main/java/com/jiashi/controller/LianZhongSyncController.java b/src/main/java/com/jiashi/controller/LianZhongSyncController.java deleted file mode 100644 index 1be1d90..0000000 --- a/src/main/java/com/jiashi/controller/LianZhongSyncController.java +++ /dev/null @@ -1,329 +0,0 @@ -package com.jiashi.controller; - -import com.google.gson.Gson; -import com.jiashi.CommonResult; -import com.jiashi.FileUploader; -import com.jiashi.dao.DataQuery; -import com.jiashi.service.CardInfo; -import com.jiashi.service.FormField; -import com.jiashi.service.Picture; -import com.jiashi.service.UploadInfo; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.CollectionUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.io.File; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.*; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * @author YongBin Wen - * @date 2024/9/26 15:32 - */ -@RestController -@Slf4j -@Api(tags = "广州市一联众同步接口") -@RequestMapping("/gzsy/lianzhong") -public class LianZhongSyncController { - - @Autowired - private DataQuery dataQuery; - - ExecutorService executor = Executors.newFixedThreadPool(10); - - @ApiOperation(value = "根据病案号和出院日期(yyyy-MM-dd)同步联众文件数据 ") - @GetMapping("/sync/byInpNoAndDisDate") - public CommonResult syncByInpNoAndDisDate(@RequestParam("inpatientNo") String inpatientNo, @RequestParam("disDate") String disDate) { - try { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - List cardInfos = dataQuery.dateQueryByInpNo(inpatientNo); - CardInfo cardInfo = null; - for (CardInfo info : cardInfos) { - if (disDate.equals(sdf.format(info.getOutdate()))) { - cardInfo = info; - break; - } - } - if (Objects.isNull(cardInfo)) { - return CommonResult.failed("未找到 cardInfo 信息!"); - } - sync(cardInfo); - return CommonResult.success("同步完成!"); - } catch (Exception ex) { - log.error(ex.getMessage(), ex); - return CommonResult.failed(ex.getMessage()); - - } - } - - - @ApiOperation(value = "联众图片数据同步检查") - @GetMapping("/sync/checkReport") - public CommonResult syncCheckReport() { - try { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - List cardInfos = dataQuery.dateQuery(2); - if (CollectionUtils.isEmpty(cardInfos)) { - return CommonResult.success("没有可检查的患者,状态=2"); - } - StringBuilder stringBuilder = new StringBuilder(); - List> futures=new ArrayList<>(); - for (CardInfo cardInfo : cardInfos) { - Future future = executor.submit(() -> check(cardInfo)); - futures.add(future); - } - for (Future future : futures) { - String result = future.get(); - if (!ObjectUtils.isEmpty(result)) { - stringBuilder.append(result).append(";\n"); - } - } - log.info("检查结果:{}",stringBuilder); - return CommonResult.success(stringBuilder.toString()); - } catch (Exception ex) { - log.error(ex.getMessage(), ex); - return CommonResult.failed(ex.getMessage()); - - } - } - - private String check(CardInfo cardInfo) throws IOException { - String dir = "c:\\pic-check\\" + cardInfo.getId(); - // 创建File对象 - File directory = new File(dir); - try { - String uniUrl = "http://192.168.8.74"; - List pictures = dataQuery.getPictures(cardInfo.getId()); - - - // 判断目录是否存在 - if (!directory.exists()) { - // 目录不存在,创建目录 - boolean created = directory.mkdirs(); - if (created) { - log.info("目录创建成功:" + dir); - } else { - log.info("目录创建失败:" + dir); - } - } - - - List faultNames = new ArrayList<>(); - for (Picture picture : pictures) { - String cmd = "C:\\Debug\\lianzhong.exe 003 192.168.8.74 " + cardInfo.getId() + " " + picture.getPicid() + " " + cardInfo.getPatno() + " " + cardInfo.getOutdateStr() + " " + picture.getPicname() + " " + picture.getCheckUpFileUrl() + " " + uniUrl + " " + picture.getRotatedegree(); - File pictureFile = new File(picture.getCheckUpFileUrl()); - int tryNum = 0; - while (tryNum <= 3) { - tryNum++; - try { - getPic(cmd); - if (pictureFile.exists()) { - break; - } - } catch (Exception ex) { - // no - } - } - - if (!pictureFile.exists()) { - faultNames.add(picture.getPicname()); - } - } - // 删除文件 - FileUploader.deleteFolder(directory); - if (faultNames.isEmpty()) { - return null; - } - String join = String.join(",", faultNames); - String result = "id" + cardInfo.getId() + ",住院号:" + cardInfo.getPatno() + ",出院日期:" + cardInfo.getOutdateStr() + ",文件:" + join + " 缺失"; - return result; - } catch (Exception ex) { - log.error("检查出错:" + ex.getMessage(), ex); - FileUploader.deleteFolder(directory); - return "住院号:" + cardInfo.getPatno() + " 出院日期:" + cardInfo.getOutdateStr() + " 检查失败!"; - } - } - - private void getPic(String cmd) throws Exception { - java.lang.Process process = java.lang.Runtime.getRuntime().exec(cmd);//执行命令生成cube - process.waitFor(); - } - - - @ApiOperation(value = "根据病案号和出院日期(yyyy-MM-dd),更新联众文件数据状态为0 ,需要重新同步 ") - @GetMapping("/updateState/byInpNoAndDisDate") - public CommonResult updateStateByInpNoAndDisDate(@RequestParam("inpatientNo") String inpatientNo, @RequestParam("disDate") String disDate) { - try { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - List cardInfos = dataQuery.dateQueryByInpNo(inpatientNo); - CardInfo cardInfo = null; - for (CardInfo info : cardInfos) { - if (disDate.equals(sdf.format(info.getOutdate()))) { - cardInfo = info; - break; - } - } - if (Objects.isNull(cardInfo)) { - return CommonResult.failed("未找到 cardInfo 信息!"); - } - dataQuery.updateBatchState(cardInfo, 0); - return CommonResult.success("更新完成!"); - } catch (Exception ex) { - log.error(ex.getMessage(), ex); - return CommonResult.failed(ex.getMessage()); - } - } - - public void sync(CardInfo cardInfo) throws IOException { - String dir = "c:\\pic-makup\\" + cardInfo.getId(); - // 创建File对象 - File directory = new File(dir); - try { - String uniUrl = "http://192.168.8.74"; - List pictures = dataQuery.getPictures(cardInfo.getId()); - if (pictures == null || pictures.size() == 0) { - //如果是空的则不同步 - dataQuery.updateBatchState(cardInfo, 5); - return; - } - - - // 判断目录是否存在 - if (!directory.exists()) { - // 目录不存在,创建目录 - boolean created = directory.mkdirs(); - if (created) { - log.info("目录创建成功:" + dir); - } else { - log.info("目录创建失败:" + dir); - } - } - List futures = new ArrayList<>(); - for (Picture picture : pictures) { - Future future = executor.submit(() -> { - try { - String cmd = "C:\\Debug\\lianzhong.exe 003 192.168.8.74 " + cardInfo.getId() + " " + picture.getPicid() + " " + cardInfo.getPatno() + " " + cardInfo.getOutdateStr() + " " + picture.getPicname() + " " + picture.getMakeUpFileUrl() + " " + uniUrl + " " + picture.getRotatedegree(); -// log.info(cmd); - java.lang.Process process = java.lang.Runtime.getRuntime().exec(cmd);//执行命令生成cube - process.waitFor(); - File pictureFile = new File(picture.getMakeUpFileUrl()); - if (!pictureFile.exists()) { - log.error("图片转换失败,命令为:{}", cmd); - } - } catch (Exception e) { - log.error(e.getMessage(), e); - e.printStackTrace(); - } - - }); - futures.add(future); - } - for (Future future : futures) { - try { - future.get(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } - } - - boolean complete = true; - List files = new ArrayList<>(); - List uploadInfos = new ArrayList<>(); - for (Picture picture : pictures) { - File pictureFile = new File(picture.getMakeUpFileUrl()); - if (!pictureFile.exists()) { - complete = false; - continue; - } - files.add(pictureFile); - UploadInfo uploadInfo = new UploadInfo(cardInfo.getPatno(), cardInfo.getOutdateStr2(), picture.getPicname(), picture.getPicname(), - picture.getPickind(), cardInfo.getId(), cardInfo.getPatname(), - cardInfo.getIndateStr(), cardInfo.getPatsex(), cardInfo.getPatnum(), - cardInfo.getIcdecode11(), cardInfo.getIcdename11(), cardInfo.getMjwesticde(), cardInfo.getMjwestname(), - cardInfo.getOutdeptname(), cardInfo.getPatciticard(), cardInfo.getOutwardname(), cardInfo.getIndeptname(), cardInfo.getIndeptcode(), cardInfo.getGestno(), cardInfo.getPatbirthdayStr()); - uploadInfos.add(uploadInfo); - } - - if (files.isEmpty()) { - dataQuery.updateBatchState(cardInfo, 4); - // 删除文件 - FileUploader.deleteFolder(directory); - return; - } - - - Map uploadInfosMap = uploadInfos.stream().collect(Collectors.toMap(UploadInfo::getUploadFileName, Function.identity())); - - - boolean success = true; - // 上传 - int totalSize = files.size(); - int batchSize = 500; - if (totalSize > batchSize) { - for (int i = 0; i < totalSize; i += batchSize) { - ArrayList batch = new ArrayList<>(); - List uploadInfoParams = new ArrayList<>(); - // 计算当前批次的结束索引 - int end = Math.min(i + batchSize, totalSize); - for (int j = i; j < end; j++) { - batch.add(files.get(j)); - uploadInfoParams.add(uploadInfosMap.get(files.get(j).getName())); - } - // 额外的表单字段参数 - List params = new ArrayList<>(); - String s = new Gson().toJson(uploadInfoParams); - params.add(new FormField("uploadFileParams", s)); - log.info("请求参数:" + cardInfo.getPatno()); - CommonResult commonResult = FileUploader.uploadFilesWithParams(batch, "http://192.168.161.102:9511/batchFileUploadJpg", params); - boolean res = commonResult.getCode() == 0; - success = success && res; - } - } else { - // 额外的表单字段参数 - List params = new ArrayList<>(); - String s = new Gson().toJson(uploadInfos); - params.add(new FormField("uploadFileParams", s)); - log.info("请求参数:" + cardInfo.getPatno()); - CommonResult commonResult = FileUploader.uploadFilesWithParams(files, "http://192.168.161.102:9511/fileUploadJpg", params); - success = commonResult.getCode() == 0; - } - - - - if (success) { - dataQuery.updateBatchState(cardInfo, 3); - - } - if (!complete) { - // 不完整 - dataQuery.updateBatchState(cardInfo, 2); - } - // 删除文件 - FileUploader.deleteFolder(directory); - } catch (IOException ex) { - if (directory.exists()) { - FileUploader.deleteFolder(directory); - } - throw ex; - } - } - - - -} diff --git a/src/main/java/com/jiashi/dao/CardInfoRepository.java b/src/main/java/com/jiashi/dao/CardInfoRepository.java index d7e4448..8160f2e 100644 --- a/src/main/java/com/jiashi/dao/CardInfoRepository.java +++ b/src/main/java/com/jiashi/dao/CardInfoRepository.java @@ -22,4 +22,14 @@ public interface CardInfoRepository extends JpaRepository, Jpa @Modifying @Query("update CardInfo set state=:state where id in :ids") public void updateState(List ids, Integer state); + + @Transactional(rollbackFor = Exception.class) + @Modifying + @Query("update CardInfo set state=:state,describe = :describe where id = :id") + void updateState(String id, Integer state, String describe); + + @Transactional(rollbackFor = Exception.class) + @Modifying + @Query("update CardInfo set findpicpath=:findpicpath where id = :id") + void updatePicPath(String id, String findpicpath); } diff --git a/src/main/java/com/jiashi/dao/DataQuery.java b/src/main/java/com/jiashi/dao/DataQuery.java index a6e2827..a4770b1 100644 --- a/src/main/java/com/jiashi/dao/DataQuery.java +++ b/src/main/java/com/jiashi/dao/DataQuery.java @@ -2,20 +2,26 @@ package com.jiashi.dao; import com.jiashi.service.CardInfo; import com.jiashi.service.Picture; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Repository; +import org.springframework.util.StringUtils; import javax.persistence.criteria.Predicate; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.List; -import java.util.Optional; @Repository +@Slf4j public class DataQuery { @@ -25,10 +31,22 @@ public class DataQuery { @Autowired private PictureRepository pictureRepository; - public List dateQuery(){ + @Value("${lz.disdate-range:}") + private String disdateRange; + + public List dateQuery() { Specification specification = (root, query, cb) -> { List predicates = new ArrayList<>(); predicates.add(cb.equal(root.get("state"), 0)); + if (StringUtils.hasText(disdateRange)) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String[] split = disdateRange.split(","); + try { + predicates.add(cb.between(root.get("outdate"), simpleDateFormat.parse(split[0]), simpleDateFormat.parse(split[1]))); + } catch (ParseException e) { + log.error("出院时间条件错误:" + disdateRange + "," + e.getMessage(), e); + } + } return cb.and(predicates.toArray(new Predicate[predicates.size()])); }; @@ -39,7 +57,7 @@ public class DataQuery { return all.toList(); } - public List dateQuery(int state){ + public List dateQuery(int state) { Specification specification = (root, query, cb) -> { List predicates = new ArrayList<>(); predicates.add(cb.equal(root.get("state"), state)); @@ -51,7 +69,7 @@ public class DataQuery { } - public List dateQueryByInpNo(String inpNo){ + public List dateQueryByInpNo(String inpNo) { Specification specification = (root, query, cb) -> { List predicates = new ArrayList<>(); predicates.add(cb.equal(root.get("patno"), inpNo)); @@ -65,32 +83,32 @@ public class DataQuery { return all.toList(); } - public void updateBatch(List cardInfos){ - for(CardInfo cardInfo:cardInfos){ + public void updateBatch(List cardInfos) { + for (CardInfo cardInfo : cardInfos) { cardInfo.setState(1); } cardInfoRepository.saveAll(cardInfos); } - public void updateBatchState(List cardInfos,Integer state){ + public void updateBatchState(List cardInfos, Integer state) { List ids = new ArrayList<>(); - for(CardInfo cardInfo:cardInfos){ - String id = cardInfo.getId(); - ids.add(id); - } - cardInfoRepository.updateState(ids,state); + for (CardInfo cardInfo : cardInfos) { + String id = cardInfo.getId(); + ids.add(id); + } + cardInfoRepository.updateState(ids, state); } - public void updateBatchState(CardInfo cardInfo,Integer state){ + public void updateBatchState(CardInfo cardInfo, Integer state) { - cardInfoRepository.updateState(cardInfo.getId(),state); + cardInfoRepository.updateState(cardInfo.getId(), state); } - public List getPictures(String FileId){ + public List getPictures(String FileId) { Specification specification = (root, query, cb) -> { List predicates = new ArrayList<>(); @@ -102,4 +120,12 @@ public class DataQuery { } + public void updateBatchState(CardInfo cardInfo, Integer state, String desc) { + cardInfoRepository.updateState(cardInfo.getId(), state, desc); + } + + + public void updatePicPath(CardInfo cardInfo, String findpicpath) { + cardInfoRepository.updatePicPath(cardInfo.getId(), findpicpath); + } } diff --git a/src/main/java/com/jiashi/service/CardInfo.java b/src/main/java/com/jiashi/service/CardInfo.java index 25ee728..fdd5379 100644 --- a/src/main/java/com/jiashi/service/CardInfo.java +++ b/src/main/java/com/jiashi/service/CardInfo.java @@ -1,6 +1,5 @@ package com.jiashi.service; -import com.jiashi.MyDateUtil; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -40,6 +39,8 @@ public class CardInfo { @Column(name="patbirthday") private Date patbirthday; private Integer state; + private String describe; + private String findpicpath; private String icdecode11; @@ -66,31 +67,6 @@ public class CardInfo { private String gestno; - - public String getPatbirthdayStr(){ - if(this.patbirthday!=null){ - try{ - return MyDateUtil.dateToString(this.patbirthday,"yyyy-MM-dd"); - }catch (Exception e){ - return ""; - } - }else{ - return ""; - } - } - - public String getOutdateStr(){ - return MyDateUtil.dateToString(this.outdate,"yyyy-MM-dd"); - } - - public String getOutdateStr2(){ - return MyDateUtil.dateToString(this.outdate,"yyyy-MM-dd HH:mm:ss"); - } - - - public String getIndateStr(){ - return MyDateUtil.dateToString(this.indate,"yyyy-MM-dd HH:mm:ss"); - } } diff --git a/src/main/java/com/jiashi/service/LianZhongUploadInfo.java b/src/main/java/com/jiashi/service/LianZhongUploadInfo.java new file mode 100644 index 0000000..5bae177 --- /dev/null +++ b/src/main/java/com/jiashi/service/LianZhongUploadInfo.java @@ -0,0 +1,105 @@ +package com.jiashi.service; + +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; + /** + * 入院日期 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/jiashi/service/Picture.java b/src/main/java/com/jiashi/service/Picture.java index 5415618..51cc3a2 100644 --- a/src/main/java/com/jiashi/service/Picture.java +++ b/src/main/java/com/jiashi/service/Picture.java @@ -28,18 +28,4 @@ public class Picture { @Column(name="pickind") private String pickind; - public String getFileUrl(){ - String fileUrl = "c:/pic/" + this.getFileid() + "/" + this.getPicname(); - return fileUrl; - } - - public String getMakeUpFileUrl(){ - String fileUrl = "c:/pic-makup/" + this.getFileid() + "/" + this.getPicname(); - return fileUrl; - } - - public String getCheckUpFileUrl(){ - String fileUrl = "c:/pic-check/" + this.getFileid() + "/" + this.getPicname(); - return fileUrl; - } } diff --git a/src/main/java/com/jiashi/service/UpdateService.java b/src/main/java/com/jiashi/service/UpdateService.java index 2153a30..a93ef7f 100644 --- a/src/main/java/com/jiashi/service/UpdateService.java +++ b/src/main/java/com/jiashi/service/UpdateService.java @@ -2,21 +2,31 @@ package com.jiashi.service; import com.google.gson.Gson; import com.jiashi.CommonResult; +import com.jiashi.FilePathUtil; import com.jiashi.FileUploader; import com.jiashi.dao.DataQuery; import lombok.extern.slf4j.Slf4j; +import net.coobird.thumbnailator.Thumbnails; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import javax.annotation.PostConstruct; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; @@ -27,188 +37,276 @@ public class UpdateService { @Autowired private DataQuery dataQuery; - public List updateData(){ + public List updateData() { List cardInfos = dataQuery.dateQuery(); - dataQuery.updateBatchState(cardInfos,1); + dataQuery.updateBatchState(cardInfos, 1); return cardInfos; } //state 状态标识。0 未开始, 1, 正在进行, 3. 已经成功。 4. 失败。5. 不需要上传的 + @PostConstruct - public void upload() { - String uniUrl = "http://192.168.8.74"; - List cardInfos = null; - ExecutorService executor2 = Executors.newFixedThreadPool(10); - ExecutorService executor = Executors.newFixedThreadPool(90); - do { - try{ - cardInfos = this.updateData(); - List futures2 = new ArrayList<>(); - for (CardInfo cardInfo : cardInfos) { - log.info("开始同步"+cardInfo.getPatno()); - Future future2 = executor2.submit(()->{ - String dir = "c:\\pic\\"+cardInfo.getId(); - // 创建File对象 - File directory = new File(dir); - try{ - List pictures = dataQuery.getPictures(cardInfo.getId()); - if(pictures==null||pictures.size()==0){ - //如果是空的则不同步 - dataQuery.updateBatchState(cardInfo,5); - return; - } + public void upload() { + log.info("联众同步数据启动>>>>>>>>>>>>>>>>>>>>"); + String syncDir = FilePathUtil.currentPath() + File.separator + "lianzhong-sync"; + FilePathUtil.mkdirs(syncDir); + + ExecutorService patientExecutors = Executors.newFixedThreadPool(10); + ExecutorService fileExecutor = Executors.newFixedThreadPool(90); + try { + while (true) { + List cardInfos = this.updateData(); + if (!CollectionUtils.isEmpty(cardInfos)) { + List patientFutures = new ArrayList<>(); + for (CardInfo cardInfo : cardInfos) { + String picDir = syncDir + File.separator + cardInfo.getId(); + FilePathUtil.mkdirs(picDir); - // 判断目录是否存在 - if (!directory.exists()) { - // 目录不存在,创建目录 - boolean created = directory.mkdirs(); - if (created) { - log.info("目录创建成功:" + dir); - } else { - log.info("目录创建失败:" + dir); + Future patientFuture = patientExecutors.submit(() -> { + try { + List pictures = dataQuery.getPictures(cardInfo.getId()); + if (CollectionUtils.isEmpty(pictures)) { + //如果是空的则不同步 + dataQuery.updateBatchState(cardInfo, 5); + FilePathUtil.deleteDir(picDir); + return; } - } - List futures = new ArrayList<>(); - for (Picture picture : pictures) { - Future future = executor.submit(() -> { - try { - String cmd = "C:\\Debug\\lianzhong.exe 003 192.168.8.74 " + cardInfo.getId() + " " + picture.getPicid() + " " + cardInfo.getPatno() + " " + cardInfo.getOutdateStr() + " " + picture.getPicname() + " " + picture.getFileUrl() + " " + uniUrl + " " + picture.getRotatedegree(); -// log.info(cmd); - java.lang.Process process = java.lang.Runtime.getRuntime().exec(cmd);//执行命令生成cube - process.waitFor(); - File pictureFile = new File(picture.getFileUrl()); - if(!pictureFile.exists()){ - log.error("图片转换失败,命令为:{}",cmd); + String lianZhongDir = findLianZhongDir(cardInfo); + if (lianZhongDir == null) { + //失败,说明原因 + dataQuery.updateBatchState(cardInfo, 2, "未找到联众数据文件夹!"); + FilePathUtil.deleteDir(picDir); + return; + } + dataQuery.updatePicPath(cardInfo, lianZhongDir); + List fileFutures = new ArrayList<>(); + for (Picture picture : pictures) { + Future fileFuture = fileExecutor.submit(() -> { + String tifFilePath = lianZhongDir + File.separator + removeFileExtension(picture.getPicname()) + ".tif"; + File tifFile = new File(tifFilePath); + if (tifFile.exists()) { + try { + BufferedImage read = ImageIO.read(tifFile); + Thumbnails.of(read) + .scale(1) + .outputFormat("jpg") + .rotate(picture.getRotatedegree()) + .toFile(picDir + File.separator + removeFileExtension(picture.getPicname()) + ".jpg"); + read.flush(); + } catch (IOException e) { + throw new RuntimeException(e); + } } - } catch (Exception e) { - log.error(e.getMessage(),e); - e.printStackTrace(); + + }); + fileFutures.add(fileFuture); + } + for (Future future : fileFutures) { + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); } + } - }); - futures.add(future); - } - for (Future future : futures) { - try { - future.get(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); + + LianZhongUploadInfo.PatientInfo patientInfo = convert(cardInfo); + List fileInfos = new ArrayList<>(); + + List faultFileNames = new ArrayList<>(); + List files = new ArrayList<>(); + for (Picture picture : pictures) { + File pictureFile = new File(picDir + File.separator + removeFileExtension(picture.getPicname()) + ".jpg"); + if (!pictureFile.exists()) { + faultFileNames.add(picture.getPicname()); + continue; + } + files.add(pictureFile); + LianZhongUploadInfo.FileInfo fileInfo=new LianZhongUploadInfo.FileInfo(); + fileInfo.setFileTitle(picture.getPicname()); + fileInfo.setUploadFileName(pictureFile.getName()); + fileInfo.setAssortId(picture.getPickind()); + // todo 应该有个排序 + fileInfo.setSort(0); + fileInfos.add(fileInfo); } - } - boolean complete = true; - List files = new ArrayList<>(); - List uploadInfos = new ArrayList<>(); - for(Picture picture : pictures){ - File pictureFile = new File(picture.getFileUrl()); - if(!pictureFile.exists()){ - complete=false; - continue; + if (files.isEmpty()) { + dataQuery.updateBatchState(cardInfo, 2,"未获取到图片!"); + // 删除文件 + FilePathUtil.deleteDir(picDir); + return; } - files.add(pictureFile); - UploadInfo uploadInfo = new UploadInfo(cardInfo.getPatno(), cardInfo.getOutdateStr2(), picture.getPicname(), picture.getPicname(), - picture.getPickind(), cardInfo.getId(), cardInfo.getPatname(), - cardInfo.getIndateStr(), cardInfo.getPatsex(),cardInfo.getPatnum(), - cardInfo.getIcdecode11(),cardInfo.getIcdename11(), cardInfo.getMjwesticde(),cardInfo.getMjwestname(), - cardInfo.getOutdeptname(),cardInfo.getPatciticard(),cardInfo.getOutwardname(),cardInfo.getIndeptname(),cardInfo.getIndeptcode(),cardInfo.getGestno(),cardInfo.getPatbirthdayStr()); - uploadInfos.add(uploadInfo); - } - if (files.isEmpty()) { - log.info("获取图片文件失败,cardInfoId:{}",cardInfo.getId()); - dataQuery.updateBatchState(cardInfo,4); - // 删除文件 - FileUploader.deleteFolder(directory); - return; - } - try { + LianZhongUploadInfo uploadInfo = new LianZhongUploadInfo(); + uploadInfo.setPatientInfo(patientInfo); + uploadInfo.setFileInfos(fileInfos); + try { + Map fileInfoMap = fileInfos.stream() + .collect(Collectors.toMap(LianZhongUploadInfo.FileInfo::getUploadFileName, Function.identity())); - Map uploadInfosMap = uploadInfos.stream().collect(Collectors.toMap(UploadInfo::getUploadFileName, Function.identity())); - - - boolean success = true; - // 上传 - int totalSize = files.size(); - int batchSize = 500; - if (totalSize > batchSize) { - for (int i = 0; i < totalSize; i += batchSize) { - ArrayList batch = new ArrayList<>(); - List uploadInfoParams = new ArrayList<>(); - // 计算当前批次的结束索引 - int end = Math.min(i + batchSize, totalSize); - for (int j = i; j < end; j++) { - batch.add(files.get(j)); - uploadInfoParams.add(uploadInfosMap.get(files.get(j).getName())); + boolean success = true; + // 上传 + int totalSize = files.size(); + int batchSize = 500; + if (totalSize > batchSize) { + for (int i = 0; i < totalSize; i += batchSize) { + ArrayList batch = new ArrayList<>(); + List uploadFileInfoList = new ArrayList<>(); + // 计算当前批次的结束索引 + int end = Math.min(i + batchSize, totalSize); + for (int j = i; j < end; j++) { + batch.add(files.get(j)); + uploadFileInfoList.add(fileInfoMap.get(files.get(j).getName())); + } + uploadInfo.setFileInfos(uploadFileInfoList); + // 额外的表单字段参数 + List params = new ArrayList<>(); + String s = new Gson().toJson(uploadInfo); + params.add(new FormField("uploadFileParams", s)); + CommonResult commonResult = FileUploader.uploadFilesWithParams(batch, "http://192.168.161.102:9511/lianzhong/batchFileUploadJpg", params); + boolean res = commonResult.getCode() == 0; + success = success && res; } + } else { // 额外的表单字段参数 List params = new ArrayList<>(); - String s = new Gson().toJson(uploadInfoParams); + String s = new Gson().toJson(uploadInfo); params.add(new FormField("uploadFileParams", s)); - log.info("请求参数:" + cardInfo.getPatno()); - CommonResult commonResult = FileUploader.uploadFilesWithParams(batch, "http://192.168.161.102:9511/batchFileUploadJpg", params); - boolean res = commonResult.getCode() == 0; - success = success && res; + CommonResult commonResult = FileUploader.uploadFilesWithParams(files, "http://192.168.161.102:9511/lianzhong/batchFileUploadJpg", params); + success = commonResult.getCode() == 0; } - } else { - // 额外的表单字段参数 - List params = new ArrayList<>(); - String s = new Gson().toJson(uploadInfos); - params.add(new FormField("uploadFileParams", s)); - log.info("请求参数:" + cardInfo.getPatno()); - CommonResult commonResult = FileUploader.uploadFilesWithParams(files, "http://192.168.161.102:9511/fileUploadJpg", params); - success = commonResult.getCode() == 0; - } - if(success){ - dataQuery.updateBatchState(cardInfo,3); + if (success) { + dataQuery.updateBatchState(cardInfo, 3); - }else{ - dataQuery.updateBatchState(cardInfo,4); + } else { + dataQuery.updateBatchState(cardInfo, 2,"上传服务端出现异常!"); + } + } catch (Exception e) { + dataQuery.updateBatchState(cardInfo, 2,e.getMessage()); + log.error(e.getMessage(), e); } - } catch (Exception e) { - dataQuery.updateBatchState(cardInfo,4); - log.error(e.getMessage(),e); - } - if (!complete) { - // 不完整 - dataQuery.updateBatchState(cardInfo,2); - } - // 删除文件 - FileUploader.deleteFolder(directory); - }catch (Exception e){ - dataQuery.updateBatchState(cardInfo,4); - log.error(e.getMessage(),e); - if (directory.exists()) { - FileUploader.deleteFolder(directory); - } - } - }); - futures2.add(future2); + if (!faultFileNames.isEmpty()) { + // 不完整 + dataQuery.updateBatchState(cardInfo, 2,String.join(",",faultFileNames+" 无法转换jpg图片!")); + } + // 删除文件 + FilePathUtil.deleteDir(picDir); + }catch (Exception ex){ + log.error(ex.getMessage(),ex); + FilePathUtil.deleteDir(picDir); + dataQuery.updateBatchState(cardInfo, 2,ex.getMessage()); + } + }); + patientFutures.add(patientFuture); + } + for (Future future : patientFutures) { + future.get(); + } + continue; } + TimeUnit.SECONDS.sleep(300); + } + } catch (Exception ex) { + log.error("联众同步数据异常:" + ex.getMessage(), ex); + } + } + private LianZhongUploadInfo.PatientInfo convert(CardInfo cardInfo) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + LianZhongUploadInfo.PatientInfo patientInfo=new LianZhongUploadInfo.PatientInfo(); + // todo 病案号 + patientInfo.setInpatientNo(null); + // todo 住院次数 + patientInfo.setAdmissTimes(null); + patientInfo.setName(cardInfo.getPatname()); + // todo 年龄 + patientInfo.setSex("") ; + patientInfo.setSexName("") ; + patientInfo.setAdmissDate(cardInfo.getIndate() == null ?null:sdf.format(cardInfo.getIndate())) ; + patientInfo.setDisDate(cardInfo.getOutdate() == null ?null:sdf.format(cardInfo.getOutdate())); + patientInfo.setAdmissDeptName(cardInfo.getIndeptname()) ; + patientInfo.setDisDeptName(cardInfo.getOutdeptname()); + patientInfo.setIdCard(cardInfo.getPatciticard()) ; + patientInfo.setMainDiagCode(null) ; + patientInfo.setMainDiagName(null) ; + patientInfo.setMainOperateCode(null); + patientInfo.setMainOperateName(null); + return patientInfo; + } - for (Future future : futures2) { - try { - future.get(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); + private String findLianZhongDir(CardInfo cardInfo) { + String gestno = cardInfo.getGestno(); + String patno = cardInfo.getPatno(); + Date outdate = cardInfo.getOutdate(); + SimpleDateFormat yearSdf = new SimpleDateFormat("yyyy"); + SimpleDateFormat yearMonthSdf = new SimpleDateFormat("yyyyMM"); + SimpleDateFormat yearMonthDaySdf = new SimpleDateFormat("yyyyMMdd"); + String yFormat = yearSdf.format(outdate); + String ymFormat = yearMonthSdf.format(outdate); + String ymdFormat = yearMonthDaySdf.format(outdate); + List archiveDirs = Arrays.asList( + "D:\\UnionNet\\ServerD", + "D:\\UnionNet\\ServerD_ny", + "D:\\UnionNet\\ServerDTemp", + "G:\\UnionNet\\ServerD", + "G:\\UnionNet\\ServerD_ny", + "G:\\UnionNet\\ServerDTemp"); + for (String archiveDir : archiveDirs) { + String ymdDateDir = archiveDir + File.separator + yFormat + File.separator + ymFormat + File.separator + ymdFormat; + File ymdDateDirFile = new File(ymdDateDir); + if (!ymdDateDirFile.exists()) { + continue; + } + File[] patPicDirs = ymdDateDirFile.listFiles(); + if (patPicDirs != null && patPicDirs.length > 0) { + for (File patPicDir : patPicDirs) { + String dirName = patPicDir.getName(); + String comparePart = dirName.substring(2).substring(0, 10); + comparePart = removeLeadingZeros(comparePart); + //TODO gestno 或者 patno 进行 识别 + boolean match = comparePart.contains(removeLeadingZeros(patno)); + if (match) { + return patPicDir.getPath(); } } - }catch(Exception e) { - log.error(e.getMessage(),e); } + } + + return null; + } + + public static String removeLeadingZeros(String str) { + if (str == null || str.isEmpty()) { + return str; // 如果字符串为空或null,直接返回 + } + int index = 0; + // 循环检查每个字符,直到找到不是'0'的字符 + while (index < str.length() && str.charAt(index) == '0') { + index++; + } + // 返回从第一个非'0'字符开始到字符串末尾的子字符串 + return str.substring(index); + } - }while (cardInfos != null && cardInfos.size() > 0) ; + public static String removeFileExtension(String fileName) { + // 检查文件名是否为空或没有后缀 + if (fileName == null || !fileName.contains(".")) { + return fileName; + } + // 找到最后一个'.'字符的位置 + int lastDotIndex = fileName.lastIndexOf('.'); + // 截取不包含后缀的部分 + return fileName.substring(0, lastDotIndex); } + + } diff --git a/src/main/java/com/jiashi/service/UploadInfo.java b/src/main/java/com/jiashi/service/UploadInfo.java deleted file mode 100644 index 642582b..0000000 --- a/src/main/java/com/jiashi/service/UploadInfo.java +++ /dev/null @@ -1,198 +0,0 @@ -package com.jiashi.service; - -import lombok.AllArgsConstructor; -import lombok.Data; - -import java.util.Date; - -/** - * [ {"inpatientNo":"35131", "disDate":"2020-07-30 00:00:00.000", "fileTitle":"0001.jpg", "uploadFileName":"1.jpg", "assortId":"078F7675CB0048EDBE586D59831C57B0" , - * "patientId":"12312312", - * "name":"长三", - * "admissDate":"住院时间", - * "sex":"男女" - * } - * ] - */ -@Data - -public class UploadInfo { - private String inpatientNo; - private String disDate; - private String fileTitle; - private String uploadFileName; - private String assortId; - private String patientId; - private String name; - private String admissDate; - private String sex; - - private Integer admissTimes; - - private String mainDiagCode; - - private String mainDiagName; - - private String mainOperateCode; - - private String mainOperateName; - - private String admissDept; - - private String admissDeptName; - - private String disDeptName; - - private String idCard; - - private String wardPalce; - - private String admissId; - - private String birthday; - - public UploadInfo(String inpatientNo, String disDate, String fileTitle, String uploadFileName, String assortId, - String patientId, String name, String admissDate, String sex,Integer admissTimes,String mainDiagCode,String mainDiagName, String mainOperateCode,String mainOperateName, - String disDeptName,String idCard,String wardPalce,String admissDeptName,String admissDept,String admissId,String birthday) { - this.inpatientNo = inpatientNo; - this.disDate = disDate; - this.fileTitle = fileTitle; - this.uploadFileName = uploadFileName; - this.assortId = assortId; - this.patientId = patientId; - this.name = name; - this.admissDate = admissDate; - this.admissTimes = admissTimes; - this.mainOperateName = mainOperateName; - this.mainDiagCode = mainDiagCode; - this.mainDiagName = mainDiagName; - this.mainOperateCode = mainOperateCode; - this.disDeptName = disDeptName; - this.idCard = idCard; - this.wardPalce = wardPalce; - this.admissDeptName = admissDeptName; - this.admissDept = admissDept; - this.admissId = admissId; - this.birthday = birthday; - this.ssAssortId(); - this.changeSexName(sex); - } - - - public void changeSexName(String sex){ - if("1".equals(sex)){ - this.sex = "男"; - }else{ - this.sex = "女"; - } - } - - public void ssAssortId() { - switch (assortId) { - case "1": - this.assortId = "1"; - break; - case "2": - this.assortId = "2"; - break; - case "3": - this.assortId = "3"; - break; - case "4": - this.assortId = "4"; - break; - case "5": - this.assortId = "5"; - break; - case "6": - this.assortId = "6"; - break; - case "7": - this.assortId = "7"; - break; - case "8": - this.assortId = "8"; - break; - case "9": - this.assortId = "9"; - break; - case "10": - this.assortId = "10"; - break; - case "11": - this.assortId = "11"; - break; - case "12": - this.assortId = "12"; - break; - case "13": - this.assortId = "13"; - break; - case "14": - this.assortId = "14"; - break; - case "15": - this.assortId = "15"; - break; - case "16": - this.assortId = "16"; - break; - case "17": - this.assortId = "17"; - break; - case "18": - this.assortId = "18"; - break; - case "19": - this.assortId = "19"; - break; - case "20": - this.assortId = "20"; - break; - case "21": - this.assortId = "21"; - break; - case "22": - this.assortId = "22"; - break; - case "23": - this.assortId = "23"; - break; - case "24": - this.assortId = "24"; - break; - case "25": - this.assortId = "25"; - break; - case "26": - this.assortId = "26"; - break; - case "27": - this.assortId = "27"; - break; - case "28": - this.assortId = "28"; - break; - case "29": - this.assortId = "29"; - break; - case "30": - this.assortId = "30"; - break; - case "31": - this.assortId = "31"; - break; - case "32": - this.assortId = "32"; - break; - case "33": - this.assortId = "33"; - break; - default: - this.assortId = "33"; - } - - - - } -} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 8bb535d..0c6dc3a 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,6 +2,9 @@ server: port: 8282 +lz: + disdate-range: 2024-01-01 00:00:00,2024-08-01 00:00:00 + spring: datasource: url: jdbc:sqlserver://192.168.8.74:1433;DatabaseName=u_medrecord