|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
@Component
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class UpdateService {
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private DataQuery dataQuery;
|
|
|
|
|
|
|
|
|
|
public List<CardInfo> updateData() {
|
|
|
|
|
List<CardInfo> cardInfos = dataQuery.dateQuery();
|
|
|
|
|
dataQuery.updateBatchState(cardInfos, 1);
|
|
|
|
|
return cardInfos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//state 状态标识。0 未开始, 1, 正在进行, 3. 已经成功。 4. 失败。5. 不需要上传的
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@PostConstruct
|
|
|
|
|
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<CardInfo> cardInfos = this.updateData();
|
|
|
|
|
if (!CollectionUtils.isEmpty(cardInfos)) {
|
|
|
|
|
List<Future> patientFutures = new ArrayList<>();
|
|
|
|
|
for (CardInfo cardInfo : cardInfos) {
|
|
|
|
|
String picDir = syncDir + File.separator + cardInfo.getId();
|
|
|
|
|
FilePathUtil.mkdirs(picDir);
|
|
|
|
|
|
|
|
|
|
Future patientFuture = patientExecutors.submit(() -> {
|
|
|
|
|
try {
|
|
|
|
|
List<Picture> pictures = dataQuery.getPictures(cardInfo.getId());
|
|
|
|
|
if (CollectionUtils.isEmpty(pictures)) {
|
|
|
|
|
//如果是空的则不同步
|
|
|
|
|
dataQuery.updateBatchState(cardInfo, 5);
|
|
|
|
|
FilePathUtil.deleteDir(picDir);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
String lianZhongDir = findLianZhongDir(cardInfo);
|
|
|
|
|
if (lianZhongDir == null) {
|
|
|
|
|
//失败,说明原因
|
|
|
|
|
dataQuery.updateBatchState(cardInfo, 2, "未找到联众数据文件夹!");
|
|
|
|
|
FilePathUtil.deleteDir(picDir);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
dataQuery.updatePicPath(cardInfo, lianZhongDir);
|
|
|
|
|
List<Future> 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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
fileFutures.add(fileFuture);
|
|
|
|
|
}
|
|
|
|
|
for (Future future : fileFutures) {
|
|
|
|
|
try {
|
|
|
|
|
future.get();
|
|
|
|
|
} catch (InterruptedException | ExecutionException e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LianZhongUploadInfo.PatientInfo patientInfo = convert(cardInfo);
|
|
|
|
|
List<LianZhongUploadInfo.FileInfo> fileInfos = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
List<String> faultFileNames = new ArrayList<>();
|
|
|
|
|
List<File> 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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (files.isEmpty()) {
|
|
|
|
|
dataQuery.updateBatchState(cardInfo, 2,"未获取到图片!");
|
|
|
|
|
// 删除文件
|
|
|
|
|
FilePathUtil.deleteDir(picDir);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
// 上传
|
|
|
|
|
int totalSize = files.size();
|
|
|
|
|
int batchSize = 500;
|
|
|
|
|
if (totalSize > batchSize) {
|
|
|
|
|
for (int i = 0; i < totalSize; i += batchSize) {
|
|
|
|
|
ArrayList<File> batch = 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));
|
|
|
|
|
uploadFileInfoList.add(fileInfoMap.get(files.get(j).getName()));
|
|
|
|
|
}
|
|
|
|
|
uploadInfo.setFileInfos(uploadFileInfoList);
|
|
|
|
|
// 额外的表单字段参数
|
|
|
|
|
List<FormField> 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<FormField> params = new ArrayList<>();
|
|
|
|
|
String s = new Gson().toJson(uploadInfo);
|
|
|
|
|
params.add(new FormField("uploadFileParams", s));
|
|
|
|
|
CommonResult commonResult = FileUploader.uploadFilesWithParams(files, "http://192.168.161.102:9511/lianzhong/batchFileUploadJpg", params);
|
|
|
|
|
success = commonResult.getCode() == 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
dataQuery.updateBatchState(cardInfo, 3);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
dataQuery.updateBatchState(cardInfo, 2,"上传服务端出现异常!");
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
dataQuery.updateBatchState(cardInfo, 2,e.getMessage());
|
|
|
|
|
log.error(e.getMessage(), e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String removeFileExtension(String fileName) {
|
|
|
|
|
// 检查文件名是否为空或没有后缀
|
|
|
|
|
if (fileName == null || !fileName.contains(".")) {
|
|
|
|
|
return fileName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 找到最后一个'.'字符的位置
|
|
|
|
|
int lastDotIndex = fileName.lastIndexOf('.');
|
|
|
|
|
|
|
|
|
|
// 截取不包含后缀的部分
|
|
|
|
|
return fileName.substring(0, lastDotIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|