You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
jp2demo/src/main/java/com/docus/demo/service/SyncBasicFileImpl.java

553 lines
25 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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.facade.ISyncBasicFileService;
import com.docus.demo.mapper.mysql.BasicMapper;
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;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.*;
import java.util.stream.Collectors;
@Slf4j
@Service
public class SyncBasicFileImpl implements ISyncBasicFileService {
@Resource
private BasicMapper basicMapper;
@Resource
private PictureMapper pictureMapper;
@Resource
private ScanAssortMapper scanAssortMapper;
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
@Value("${savePath}")
private String savePath;
private final ExecutorService executor = new ThreadPoolExecutor(5, 10,
30L, TimeUnit.DAYS,
new LinkedBlockingQueue<Runnable>());
@Override
public CommonResult<?> syncBasicFile(SyncFileDto syncFileDto) {
//页码
int current;
//每页1000条数据
int limit = syncFileDto.getLimit();
//1.先去tbaisc查数据 查询出带cid的数据
BasicSelectDto basicSelectDto = new BasicSelectDto();
basicSelectDto.setStartDate(syncFileDto.getStartDate());
basicSelectDto.setEndDate(syncFileDto.getEndDate());
basicSelectDto.setInpatientNoList(syncFileDto.getInpatientNoList());
// log.info("这里报错了吗2");
List<BasicVo> basicVoList;
for (current = 1; ; current++) {
// log.info("开始查询"+basicSelectDto);
basicVoList = basicMapper.getBasicVoList((current - 1) * limit, limit, basicSelectDto, basicSelectDto.getInpatientNoList());
if (null == basicVoList || basicVoList.size() == 0) {
log.info("查询不到基础数据");
break;
}
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (BasicVo basicVo : basicVoList) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
List<TCardInfo> cardInfoByCid = pictureMapper.getCardInfoByCid(basicVo.getBColumn5());
if (ObjectUtil.isEmpty(cardInfoByCid)) {
log.info("找不到联众基础信息" + basicVo.getBColumn5());
return;
}
TCardInfo tCardInfo = cardInfoByCid.get(0);
List<ScanAssort> oldScanAssort = scanAssortMapper.getListByPid(basicVo.getPatientId());
if (oldScanAssort.size() != 0 && oldScanAssort.get(0).getCreater().equals("auto7")) {
if (syncFileDto.getIsSkipOverRide() == 1) {
log.info("跳过同步" + basicVo.getInpatientNo() + " 住院次数" + basicVo.getAdmissTimes());
return;
}
}
log.info(syncFileDto.getStartDate() + " ------ " + syncFileDto.getEndDate());
List<ScanAssort> updateOrInsertList = new ArrayList<>(1000);
log.info("图片开始同步" + basicVo.getInpatientNo() + " 住院次数" + basicVo.getAdmissTimes());
List<ScanAssort> scanAssortList = new ArrayList<>();
try {
scanAssortList = this.doSyncFile(basicVo, tCardInfo);
} catch (Exception e) {
log.error("图片同步失败", e);
}
// log.info("图片同步结束");
//2.5数据入库
if (scanAssortList.size() != 0) {
// log.info("查询到的3.0旧数据"+oldScanAssort.size());
//根据pid 查询数据库 根据路径和名称做匹配 如果数据存在需要做幂等 不存在需要做数据更新
List<ScanAssort> addScanAssortList = this.handleUpdateOrInsert(oldScanAssort, scanAssortList);
updateOrInsertList.addAll(addScanAssortList);
} else {
// log.info(basicVo.getInpatientNo() + " canFindImage ");
}
if (ObjectUtil.isNotEmpty(updateOrInsertList)) {
scanAssortMapper.insertOrUpdateBatch(updateOrInsertList);
basicMapper.updateScanStatus(basicVo.getPatientId());
}
log.info("结束同步" + basicVo.getInpatientNo() + " size " + updateOrInsertList.size());
} catch (Exception e) {
log.info("同步出现异常" + e.getMessage() + e);
}
}, executor);
futures.add(future);
log.info("本次同步基础数据大小" + basicVoList.size());
}
for (CompletableFuture<Void> future : futures) {
future.join();
}
}
return CommonResult.success("同步成功");
}
@Override
public CommonResult<?> deleteSync(SyncBasicDataDto syncFileDto) {
try {
//页码
int current;
//每页1000条数据
int limit = syncFileDto.getLimit();
//1.先去tbaisc查数据 查询出带cid的数据
BasicSelectDto basicSelectDto = new BasicSelectDto();
basicSelectDto.setStartDate(syncFileDto.getStartDate());
basicSelectDto.setEndDate(syncFileDto.getEndDate());
List<BasicVo> basicVoList;
for (current = 1; ; current++) {
basicVoList = basicMapper.getBasicVoList((current - 1) * limit, limit, basicSelectDto, syncFileDto.getInpatientNoList());
if (null == basicVoList || basicVoList.size() == 0) {
log.info("程序停止");
break;
}
log.info("查询到的数据量大小" + basicVoList.size());
List<String> deletePidList = new ArrayList<>(basicVoList.size());
for (BasicVo basicVo : basicVoList) {
String[] disDate = dateFormat.format(basicVo.getDisDate()).split("-");
String cyYear = disDate[0];
String cyMonth = disDate[1];
String cyDay = disDate[2];
String outDir = "F:\\lianzhong" + File.separator
+ cyYear + File.separator
+ cyMonth + File.separator
+ cyDay + File.separator
+ basicVo.getInpatientNo() + File.separator;
List<ScanAssort> oldScanAssort = scanAssortMapper.getListByPid(basicVo.getPatientId());
if (oldScanAssort.size() != 0) {
ScanAssort scanAssort = oldScanAssort.get(oldScanAssort.size() - 1);
String path = outDir + scanAssort.getScanPage();
File file = new File(path);
if (!file.exists()) {
deletePidList.add(basicVo.getPatientId());
}
}
}
log.info("删除数据量大小" + deletePidList.size());
if (deletePidList.size() != 0) {
scanAssortMapper.deleteByPid(deletePidList);
}
}
} catch (Exception e) {
log.info("删除异常" + e.getMessage());
}
return CommonResult.success("清理成功");
}
@Override
public CommonResult<?> fileUploadJpg(MultipartFile[] files, UploadJpgFileParam uploadJpgFileParam) {
try {
if (Objects.isNull(uploadJpgFileParam) || Objects.isNull(uploadJpgFileParam.getUploadFileParams())) {
log.info("文件上传参数为空!");
return CommonResult.failed("文件上传参数为空!");
}
//解析文件上传参数
List<FileUploadJpgDto> fileUploadJpg = JSONArray.parseArray(uploadJpgFileParam.getUploadFileParams(), FileUploadJpgDto.class);
for (FileUploadJpgDto dto : fileUploadJpg) {
if (StrUtil.isBlank(dto.getPatientId())) {
log.info("PatientId为空");
return CommonResult.failed("PatientId不能为空");
}
}
ArrayList<Tbasic> tbasics = new ArrayList<>();
ArrayList<ScanAssort> scanAssorts = new ArrayList<>();
String patientId = fileUploadJpg.get(0).getPatientId();
Integer admissTimes = fileUploadJpg.get(0).getAdmissTimes();
String admissId = fileUploadJpg.get(0).getAdmissId();
//组织基础数据
Tbasic tbasic = this.getTbasic(fileUploadJpg);
tbasics.add(tbasic);
//查询是否存在更新,不存在新增
String basicPatientId = basicMapper.getTbasicPatientId(admissId);
if (StringUtils.isBlank(basicPatientId)) {
if (!basicMapper.addBasic(tbasics)) {
log.info("新增PatientId为:" + patientId + "的基础数据失败");
return CommonResult.failed("新增PatientId为:" + patientId + "的基础数据失败");
} else {
log.info("新增PatientId为:" + patientId + "的基础数据成功");
}
} else {
//存在时先删除基础数据图像数据,后新增
if (basicMapper.delTbasicByPatientId(admissId)) {
//删除路径图像
List<ScanAssort> scanAssort = scanAssortMapper.getScanAssort(basicPatientId);
if (!CollectionUtils.isEmpty(scanAssort)){
for (ScanAssort list:scanAssort){
File file = new File(list.getImagePath()+File.separatorChar+list.getScanPage());
try {
file.delete(); // 删除照片
} catch (Exception e) {
e.printStackTrace();
}
}
}
//删除文件数据
scanAssortMapper.delScanAssort(basicPatientId);
if (!basicMapper.addBasic(tbasics)) {
log.info("新增PatientId为:" + patientId + "的基础数据失败");
return CommonResult.failed("新增PatientId为:" + patientId + "的基础数据失败");
} else {
log.info("新增PatientId为:" + patientId + "的基础数据成功");
}
}
}
if (fileUploadJpg.size() != files.length) {
log.info(patientId + "文件上传数量与参数不一致!");
return CommonResult.failed("文件上传数量与参数不一致");
}
// 参数不含上传的,不匹配
List<String> originalFileNames = fileUploadJpg.stream().map(item -> String.valueOf(item.getUploadFileName())).collect(Collectors.toList());
for (MultipartFile file : files) {
if (!originalFileNames.contains(file.getOriginalFilename())) {
log.info("文件名:" + file.getOriginalFilename() + "与病案号:" + patientId + "集合中文件名不匹配");
return CommonResult.failed("文件名:" + file.getOriginalFilename() + "与病案号:" + patientId + "集合中中文名不匹配");
}
}
//文件保存目录
String filePathdir = savePath + File.separatorChar + patientId + File.separatorChar + admissTimes;
File filePath = new File(filePathdir);
//判断文件夹是否存在不存在创建文件夹
if (!filePath.exists()) {
filePath.mkdirs();
}
//保存文件
for (MultipartFile file : files) {
for (FileUploadJpgDto dto : fileUploadJpg) {
//上传原文件名与实际文件名一致
if (dto.getUploadFileName().equals(file.getOriginalFilename())) {
//记录排序
final int[] sort = {0};
ScanAssort tScanAssortDto = addScanAssort(patientId, filePathdir, file, dto, sort);
if (Objects.isNull(tScanAssortDto)) {
log.info("病案主键:" + patientId + "中" + dto.getFileTitle() + "中保存失败");
} else {
scanAssorts.add(tScanAssortDto);
}
}
}
}
if (!scanAssortMapper.addScanAssort(scanAssorts)) {
log.info(patientId + "保存数据库失败");
return CommonResult.failed(patientId + "保存数据库失败");
}
log.info("本次传输成功病案主键为:" + patientId);
} catch (Exception e) {
return CommonResult.failed("保存失败!异常处理" + e.getMessage());
}
return CommonResult.success("完成");
}
private ScanAssort addScanAssort(String patientId, String filePathdir, MultipartFile file, FileUploadJpgDto dto, int[] sort) {
//文件保存地址
String toJpgFilePath = filePathdir + File.separatorChar + dto.getUploadFileName();
try {
file.transferTo(new File(toJpgFilePath));
} catch (IOException e) {
log.info("将pdf文件保存本地失败" + dto.getUploadFileName() + "," + e.getMessage());
return null;
}
//组织新数据
ScanAssort scanAssort = new ScanAssort();
scanAssort.setId(SnowflakeIdWorker.idWorker.nextId());
scanAssort.setPatientId(patientId);
scanAssort.setAssortId(dto.getAssortId());
scanAssort.setFileTitle(dto.getFileTitle());
scanAssort.setImagePath(filePathdir);
scanAssort.setCreateTime(new Date());
scanAssort.setScanPage(dto.getUploadFileName());
scanAssort.setSort(sort[0]);
scanAssort.setFileSource(2);
scanAssort.setFileStorageType(1);
scanAssort.setFilePages(1);
sort[0] += 1;
return scanAssort;
}
private Tbasic getTbasic(List<FileUploadJpgDto> fileUploadJpg) {
FileUploadJpgDto fileUploadJpgDto = fileUploadJpg.get(0);
Tbasic tbasic = new Tbasic();
tbasic.setPatientId(fileUploadJpgDto.getPatientId());
tbasic.setAdmissTimes(fileUploadJpgDto.getAdmissTimes());
tbasic.setInpatientNo(fileUploadJpgDto.getInpatientNo());
tbasic.setAdmissId(fileUploadJpgDto.getAdmissId());
tbasic.setName(fileUploadJpgDto.getName());
tbasic.setSex(fileUploadJpgDto.getSex());
tbasic.setAge(fileUploadJpgDto.getAge());
if (StringUtils.isNotBlank(fileUploadJpgDto.getIdCard())) {
tbasic.setIdCard(fileUploadJpgDto.getIdCard());
}
tbasic.setAdmissDate(fileUploadJpgDto.getAdmissDate());
if (StringUtils.isNotBlank(fileUploadJpgDto.getAdmissDept())) {
tbasic.setAdmissDept(fileUploadJpgDto.getAdmissDept());
}
if (StringUtils.isNotBlank(fileUploadJpgDto.getAdmissDeptName())) {
tbasic.setAdmissDeptName(fileUploadJpgDto.getAdmissDeptName());
}
tbasic.setDisDate(fileUploadJpgDto.getDisDate());
if (StringUtils.isNotBlank(fileUploadJpgDto.getDisDept())) {
tbasic.setDisDept(fileUploadJpgDto.getDisDept());
}
if (StringUtils.isNotBlank(fileUploadJpgDto.getDisDeptName())) {
tbasic.setDisDeptName(fileUploadJpgDto.getDisDeptName());
}
if (StringUtils.isNotBlank(fileUploadJpgDto.getMainDiagName())) {
tbasic.setMainDiagName(fileUploadJpgDto.getMainDiagName());
}
if (StringUtils.isNotBlank(fileUploadJpgDto.getMainDiagCode())) {
tbasic.setMainDiagCode(fileUploadJpgDto.getMainDiagCode());
}
if (StringUtils.isNotBlank(fileUploadJpgDto.getMainOperateName())) {
tbasic.setMainOperateName(fileUploadJpgDto.getMainOperateName());
}
if (StringUtils.isNotBlank(fileUploadJpgDto.getMainOperateCode())) {
tbasic.setMainOperateCode(fileUploadJpgDto.getMainOperateCode());
}
tbasic.setBColumn8(1);
tbasic.setIsArchive(1);
tbasic.setArchiveFileStorageType(2);
tbasic.setCreateTime(new Date());
tbasic.setFileSource(2);
tbasic.setWardPalce(fileUploadJpgDto.getWardPalce());
return tbasic;
}
private List<ScanAssort> handleUpdateOrInsert(List<ScanAssort> oldScanAssort, List<ScanAssort> scanAssortList) {
//如果没有旧数据 做全量插入
if (ObjectUtil.isEmpty(oldScanAssort)) {
return scanAssortList;
}
//做新增或者插入
return scanAssortList.stream().peek(m -> {
//根据路径和文件名称去旧数据做判断 如果存在则需要做更新
ScanAssort scanAssort = oldScanAssort.stream()
.filter(f -> ObjectUtil.equal(m.getImagePath(), f.getImagePath()) && ObjectUtil.equal(m.getScanPage(), f.getScanPage()))
.findAny()
.orElse(null);
if (scanAssort != null) {
m.setId(scanAssort.getId());
}
}).collect(Collectors.toList());
}
private List<ScanAssort> doSyncFile(BasicVo basicVo, TCardInfo tCardInfo) {
List<ScanAssort> scanAssortList = new ArrayList<>(100);
String cuid = basicVo.getBColumn5();
String format = dateFormat.format(basicVo.getDisDate());
String[] disDate = format.split("-");
String cyYear = disDate[0];
String cyMonth = disDate[1];
String cyDay = disDate[2];
// List<TPictureTransfer> pictureTransferInfoByCid = pictureMapper.getPictureTransferInfoByCid(cuid);
// if (ObjectUtil.isEmpty(pictureTransferInfoByCid)){
// return scanAssortList;
// }
//
// TPictureTransfer tPictureTransfer = pictureTransferInfoByCid.get(0);
// if (ObjectUtil.isEmpty(tPictureTransfer.getHostReason())) {
// return scanAssortList;
// }
// String rootDir = tPictureTransfer.getHostReason() + File.separator;
// log.info(tPictureTransfer.getHostReason().length()+" ------------------- ");
// if (tPictureTransfer.getHostReason().length() < 30) {
// String rootDir = getRootDir("Z", basicVo, cyYear, cyMonth, cyDay);
// if (rootDir == null) {
// rootDir = getRootDir("Y", basicVo, cyYear, cyMonth, cyDay);
// }
// }
ExecutorService executor = new ThreadPoolExecutor(5, 5,
30L, TimeUnit.DAYS,
new LinkedBlockingQueue<Runnable>());
String outDir = "F:\\lianzhong" + File.separator
+ cyYear + File.separator
+ cyMonth + File.separator
+ cyDay + File.separator
+ basicVo.getInpatientNo();
// 2.根据cid查询联众表t_picture 走索引大概零点几秒
List<TPicture> tPictureList = pictureMapper.getPictureInfoByCid(cuid);
log.info("查询到的联众数据" + tPictureList.size());
// 2.1根据病案信息拼接地址
List<CompletableFuture<Void>> futures = new ArrayList<>();
final int[] sort = {0};
for (TPicture tpicture : tPictureList) {
// 创建一个有返回值的异步任务
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
String picName = tpicture.getPicName().split(".jpg")[0];
// String inPutFile = rootDir + picName + ".tif";
String outFile = outDir + File.separator + picName + ".jpg";
// File file = new File(inPutFile);
// if (!file.exists()){
// log.info(basicVo.getInpatientNo()+"文件未找到"+inPutFile);
// }
log.info("开始转换文件" + picName);
boolean savePicFlag = false;
// 2.2jp2转化jpg 图片通过文件流写到挂在的盘符
// savePicFlag = ImageUtils.getInstance().savePic(inPutFile, outFile, tpicture.getRotateDegree());
// log.info("是否转换成功"+savePicFlag);
// if (!savePicFlag){
// log.info(basicVo.getInpatientNo()+"找不到tif数据 开始同步jp2"+picName);
// //需要同步tif文件成jpg过来
// inPutFile = rootDir + picName + ".jp2";
// savePicFlag = ImageUtils.getInstance().savePic(inPutFile, outFile, tpicture.getRotateDegree());
// }
// 2.4组合文件信息
ScanAssort scanAssort = new ScanAssort();
synchronized (this) {
scanAssort.setId(SnowflakeIdWorker.idWorker.nextId());
scanAssort.setPatientId(basicVo.getPatientId());
scanAssort.setAssortId(tpicture.getPicKind());
scanAssort.setFileTitle(picName);
scanAssort.setImagePath(outDir);
scanAssort.setCreateTime(new Date());
scanAssort.setScanPage(picName + ".jpg");
scanAssort.setSort(sort[0]);
scanAssort.setFileSource(2);
scanAssort.setFileStorageType(1);
scanAssort.setFilePages(1);
sort[0] += 1;
}
String cmd = "C:\\Debug\\lianzhong.exe 003 192.168.8.74 " + tCardInfo.getId() + " " + tpicture.getPicId() + " " + tCardInfo.getPatno() + " " + format + " " + picName + ".jpg " + outFile + " http://192.168.8.74" + tpicture.getRotateDegree();
try {
Process exec = Runtime.getRuntime().exec(cmd);
int i = exec.waitFor();
savePicFlag = i == 0;
} catch (Exception e) {
log.info("执行命令失败{}", e.getMessage());
e.printStackTrace();
}
if (savePicFlag) {
log.info(basicVo.getInpatientNo() + "次数" + basicVo.getAdmissTimes() + "同步成功" + picName);
scanAssort.setCreater("auto7");
} else {
log.info(basicVo.getInpatientNo() + "次数" + basicVo.getAdmissTimes() + "失败");
scanAssort.setCreater("auto4");
}
scanAssortList.add(scanAssort);
}, executor);
// 获取异步任务的结果
futures.add(future);
}
for (CompletableFuture<Void> future : futures) {
future.join();
}
return scanAssortList;
}
private String getRootDir(String pan, BasicVo basicInfo, String cyYear, String cyMonth, String cyDay) {
String inpatientNo = basicInfo.getInpatientNo().trim();
String rootDir = pan + ":\\"
+ cyYear + File.separator
+ cyYear + cyMonth + File.separator
+ cyYear + cyMonth + cyDay;
File file = new File(rootDir);
File[] subdirectories = file.listFiles(File::isDirectory);
if (subdirectories != null) {
//判断当前日期下是否有路径
for (File subFile : subdirectories) {
if (subFile.getName().contains(inpatientNo)) {
rootDir = rootDir + File.separator + subFile.getName() + File.separator;
return rootDir;
}
}
}
for (int day = 1; day < 32; day++) {
String otherDay = String.format("%02d", day);
rootDir = pan + ":\\"
+ cyYear + File.separator
+ cyYear + cyMonth + File.separator
+ cyYear + cyMonth + otherDay;
file = new File(rootDir);
subdirectories = file.listFiles(File::isDirectory);
if (subdirectories != null) {
//判断当前日期下是否有路径
for (File subFile : subdirectories) {
if (subFile.getName().contains(inpatientNo)) {
rootDir = rootDir + File.separator + subFile.getName() + File.separator;
return rootDir;
}
}
}
}
return null;
}
}