package com.docus.demo.service; import cn.hutool.core.util.ObjectUtil; import com.docus.demo.dto.BasicSelectDto; import com.docus.demo.dto.SyncBasicDataDto; import com.docus.demo.dto.SyncFileDto; 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.ImageUtils; import com.docus.demo.utils.MyImageUtils; import com.docus.demo.utils.SnowflakeIdWorker; import com.docus.demo.vo.BasicVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; 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.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"); private final ExecutorService executor = new ThreadPoolExecutor(3, 3, 30L, TimeUnit.DAYS, new LinkedBlockingQueue()); @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 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; } for (BasicVo basicVo : basicVoList) { CompletableFuture.runAsync(() -> { try { List cardInfoByCid = pictureMapper.getCardInfoByCid(basicVo.getBColumn5()); if (ObjectUtil.isEmpty(cardInfoByCid)) { log.info("找不到联众基础信息" + basicVo.getBColumn5()); return; } TCardInfo tCardInfo = cardInfoByCid.get(0); List 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 updateOrInsertList = new ArrayList<>(1000); log.info("图片开始同步" + basicVo.getInpatientNo() + " 住院次数" + basicVo.getAdmissTimes()); List 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 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); } log.info("本次同步基础数据大小" + basicVoList.size()); } 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 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 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 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("清理成功"); } private List handleUpdateOrInsert(List oldScanAssort, List 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 doSyncFile(BasicVo basicVo, TCardInfo tCardInfo) { List 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 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(30, 30, 30L, TimeUnit.DAYS, new LinkedBlockingQueue()); String outDir = "F:\\lianzhong" + File.separator + cyYear + File.separator + cyMonth + File.separator + cyDay + File.separator + basicVo.getInpatientNo(); // 2.根据cid查询联众表t_picture 走索引大概零点几秒 List tPictureList = pictureMapper.getPictureInfoByCid(cuid); log.info("查询到的联众数据" + tPictureList.size()); // 2.1根据病案信息拼接地址 List> futures = new ArrayList<>(); final int[] sort = {0}; for (TPicture tpicture : tPictureList) { // 创建一个有返回值的异步任务 CompletableFuture 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); } 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; } }