feat: 厦门中医院联众采集端

厦门中医院联众-XiaMenZhongLianZhong
wyb 6 months ago
parent c316a76c66
commit 93b710be70

@ -102,6 +102,25 @@
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-jpeg</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-tiff</artifactId>
<version>3.8.1</version>
</dependency>
</dependencies>
<build>

@ -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));
}
}

@ -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;

@ -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<String> syncByInpNoAndDisDate(@RequestParam("inpatientNo") String inpatientNo, @RequestParam("disDate") String disDate) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
List<CardInfo> 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<String> syncCheckReport() {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
List<CardInfo> cardInfos = dataQuery.dateQuery(2);
if (CollectionUtils.isEmpty(cardInfos)) {
return CommonResult.success("没有可检查的患者,状态=2");
}
StringBuilder stringBuilder = new StringBuilder();
List<Future<String>> futures=new ArrayList<>();
for (CardInfo cardInfo : cardInfos) {
Future<String> future = executor.submit(() -> check(cardInfo));
futures.add(future);
}
for (Future<String> 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<Picture> pictures = dataQuery.getPictures(cardInfo.getId());
// 判断目录是否存在
if (!directory.exists()) {
// 目录不存在,创建目录
boolean created = directory.mkdirs();
if (created) {
log.info("目录创建成功:" + dir);
} else {
log.info("目录创建失败:" + dir);
}
}
List<String> 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<String> updateStateByInpNoAndDisDate(@RequestParam("inpatientNo") String inpatientNo, @RequestParam("disDate") String disDate) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
List<CardInfo> 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<Picture> 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<Future> 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<File> files = new ArrayList<>();
List<UploadInfo> 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<String, UploadInfo> 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<File> batch = new ArrayList<>();
List<UploadInfo> 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<FormField> 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<FormField> 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;
}
}
}

@ -22,4 +22,14 @@ public interface CardInfoRepository extends JpaRepository<CardInfo, String>, Jpa
@Modifying
@Query("update CardInfo set state=:state where id in :ids")
public void updateState(List<String> 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);
}

@ -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<CardInfo> dateQuery(){
@Value("${lz.disdate-range:}")
private String disdateRange;
public List<CardInfo> dateQuery() {
Specification<CardInfo> specification = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(root.<String>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.<Date>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<CardInfo> dateQuery(int state){
public List<CardInfo> dateQuery(int state) {
Specification<CardInfo> specification = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(root.<String>get("state"), state));
@ -51,7 +69,7 @@ public class DataQuery {
}
public List<CardInfo> dateQueryByInpNo(String inpNo){
public List<CardInfo> dateQueryByInpNo(String inpNo) {
Specification<CardInfo> specification = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(root.<String>get("patno"), inpNo));
@ -65,32 +83,32 @@ public class DataQuery {
return all.toList();
}
public void updateBatch(List<CardInfo> cardInfos){
for(CardInfo cardInfo:cardInfos){
public void updateBatch(List<CardInfo> cardInfos) {
for (CardInfo cardInfo : cardInfos) {
cardInfo.setState(1);
}
cardInfoRepository.saveAll(cardInfos);
}
public void updateBatchState(List<CardInfo> cardInfos,Integer state){
public void updateBatchState(List<CardInfo> cardInfos, Integer state) {
List<String> ids = new ArrayList<>();
for(CardInfo cardInfo:cardInfos){
for (CardInfo cardInfo : cardInfos) {
String id = cardInfo.getId();
ids.add(id);
}
cardInfoRepository.updateState(ids,state);
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<Picture> getPictures(String FileId){
public List<Picture> getPictures(String FileId) {
Specification<Picture> specification = (root, query, cb) -> {
List<Predicate> 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);
}
}

@ -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");
}
}

@ -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;
/**
* 12
*/
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<FileInfo> fileInfos;
}

@ -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;
}
}

@ -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,108 +37,115 @@ public class UpdateService {
@Autowired
private DataQuery dataQuery;
public List<CardInfo> updateData(){
public List<CardInfo> updateData() {
List<CardInfo> 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<CardInfo> cardInfos = null;
ExecutorService executor2 = Executors.newFixedThreadPool(10);
ExecutorService executor = Executors.newFixedThreadPool(90);
do {
try{
cardInfos = this.updateData();
List<Future> futures2 = new ArrayList<>();
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<CardInfo> cardInfos = this.updateData();
if (!CollectionUtils.isEmpty(cardInfos)) {
List<Future> patientFutures = 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{
String picDir = syncDir + File.separator + cardInfo.getId();
FilePathUtil.mkdirs(picDir);
Future patientFuture = patientExecutors.submit(() -> {
try {
List<Picture> pictures = dataQuery.getPictures(cardInfo.getId());
if(pictures==null||pictures.size()==0){
if (CollectionUtils.isEmpty(pictures)) {
//如果是空的则不同步
dataQuery.updateBatchState(cardInfo,5);
dataQuery.updateBatchState(cardInfo, 5);
FilePathUtil.deleteDir(picDir);
return;
}
// 判断目录是否存在
if (!directory.exists()) {
// 目录不存在,创建目录
boolean created = directory.mkdirs();
if (created) {
log.info("目录创建成功:" + dir);
} else {
log.info("目录创建失败:" + dir);
}
String lianZhongDir = findLianZhongDir(cardInfo);
if (lianZhongDir == null) {
//失败,说明原因
dataQuery.updateBatchState(cardInfo, 2, "未找到联众数据文件夹!");
FilePathUtil.deleteDir(picDir);
return;
}
List<Future> futures = new ArrayList<>();
dataQuery.updatePicPath(cardInfo, lianZhongDir);
List<Future> fileFutures = new ArrayList<>();
for (Picture picture : pictures) {
Future future = executor.submit(() -> {
Future fileFuture = fileExecutor.submit(() -> {
String tifFilePath = lianZhongDir + File.separator + removeFileExtension(picture.getPicname()) + ".tif";
File tifFile = new File(tifFilePath);
if (tifFile.exists()) {
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);
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();
}
});
futures.add(future);
fileFutures.add(fileFuture);
}
for (Future future : futures) {
for (Future future : fileFutures) {
try {
future.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
boolean complete = true;
LianZhongUploadInfo.PatientInfo patientInfo = convert(cardInfo);
List<LianZhongUploadInfo.FileInfo> fileInfos = new ArrayList<>();
List<String> faultFileNames = new ArrayList<>();
List<File> files = new ArrayList<>();
List<UploadInfo> uploadInfos = new ArrayList<>();
for(Picture picture : pictures){
File pictureFile = new File(picture.getFileUrl());
if(!pictureFile.exists()){
complete=false;
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);
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);
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);
}
if (files.isEmpty()) {
log.info("获取图片文件失败,cardInfoId:{}",cardInfo.getId());
dataQuery.updateBatchState(cardInfo,4);
dataQuery.updateBatchState(cardInfo, 2,"未获取到图片!");
// 删除文件
FileUploader.deleteFolder(directory);
FilePathUtil.deleteDir(picDir);
return;
}
try {
Map<String, UploadInfo> uploadInfosMap = uploadInfos.stream().collect(Collectors.toMap(UploadInfo::getUploadFileName, Function.identity()));
LianZhongUploadInfo uploadInfo = new LianZhongUploadInfo();
uploadInfo.setPatientInfo(patientInfo);
uploadInfo.setFileInfos(fileInfos);
try {
Map<String, LianZhongUploadInfo.FileInfo> fileInfoMap = fileInfos.stream()
.collect(Collectors.toMap(LianZhongUploadInfo.FileInfo::getUploadFileName, Function.identity()));
boolean success = true;
// 上传
@ -137,78 +154,159 @@ public class UpdateService {
if (totalSize > batchSize) {
for (int i = 0; i < totalSize; i += batchSize) {
ArrayList<File> batch = new ArrayList<>();
List<UploadInfo> uploadInfoParams = new ArrayList<>();
List<LianZhongUploadInfo.FileInfo> uploadFileInfoList = 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()));
uploadFileInfoList.add(fileInfoMap.get(files.get(j).getName()));
}
uploadInfo.setFileInfos(uploadFileInfoList);
// 额外的表单字段参数
List<FormField> 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);
CommonResult commonResult = FileUploader.uploadFilesWithParams(batch, "http://192.168.161.102:9511/lianzhong/batchFileUploadJpg", params);
boolean res = commonResult.getCode() == 0;
success = success && res;
}
} else {
// 额外的表单字段参数
List<FormField> params = new ArrayList<>();
String s = new Gson().toJson(uploadInfos);
String s = new Gson().toJson(uploadInfo);
params.add(new FormField("uploadFileParams", s));
log.info("请求参数:" + cardInfo.getPatno());
CommonResult commonResult = FileUploader.uploadFilesWithParams(files, "http://192.168.161.102:9511/fileUploadJpg", params);
CommonResult commonResult = FileUploader.uploadFilesWithParams(files, "http://192.168.161.102:9511/lianzhong/batchFileUploadJpg", 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,4);
log.error(e.getMessage(),e);
dataQuery.updateBatchState(cardInfo, 2,e.getMessage());
log.error(e.getMessage(), e);
}
if (!complete) {
if (!faultFileNames.isEmpty()) {
// 不完整
dataQuery.updateBatchState(cardInfo,2);
dataQuery.updateBatchState(cardInfo, 2,String.join(",",faultFileNames+" 无法转换jpg图片"));
}
// 删除文件
FileUploader.deleteFolder(directory);
}catch (Exception e){
dataQuery.updateBatchState(cardInfo,4);
log.error(e.getMessage(),e);
if (directory.exists()) {
FileUploader.deleteFolder(directory);
}
FilePathUtil.deleteDir(picDir);
}catch (Exception ex){
log.error(ex.getMessage(),ex);
FilePathUtil.deleteDir(picDir);
dataQuery.updateBatchState(cardInfo, 2,ex.getMessage());
}
});
futures2.add(future2);
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<String> 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;
}
}while (cardInfos != null && cardInfos.size() > 0) ;
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);
}
public static String removeFileExtension(String fileName) {
// 检查文件名是否为空或没有后缀
if (fileName == null || !fileName.contains(".")) {
return fileName;
}
// 找到最后一个'.'字符的位置
int lastDotIndex = fileName.lastIndexOf('.');
// 截取不包含后缀的部分
return fileName.substring(0, lastDotIndex);
}
}

@ -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";
}
}
}

@ -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

Loading…
Cancel
Save