package com.docus.demo.service; import cn.hutool.core.util.ObjectUtil; import com.docus.demo.dto.BasicSelectDto; import com.docus.demo.dto.SyncFileDto; import com.docus.demo.entity.CommonResult; import com.docus.demo.entity.ScanAssort; import com.docus.demo.entity.TPicture; import com.docus.demo.entity.ZdAssort; 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.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 java.io.File; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; @Slf4j @Service public class SyncBasicFileImpl implements ISyncBasicFileService { @Autowired private BasicMapper basicMapper; @Autowired private PictureMapper pictureMapper; @Autowired private ScanAssortMapper scanAssortMapper; private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); private final ExecutorService executor = Executors.newFixedThreadPool(7); @Override public CommonResult syncBasicFile(SyncFileDto syncFileDto) { CompletableFuture.runAsync(() -> { // System.out.println("开始执行多线程同步" +syncFileDto.getStartDate() +" " +syncFileDto.getEndDate()); //页码 int current; //每页1000条数据 int limit = syncFileDto.getLimit(); //1.先去tbaisc查数据 查询出带cid的数据 // System.out.println("查询基础信息组装"); BasicSelectDto basicSelectDto = this.getBaiscSelectDto(syncFileDto); List basicVoList; // System.out.println("查询基础信息组装结束"); for (current = 1; ; current++) { // System.out.println("查询基础"); basicVoList = basicMapper.getBasicVoList((current-1)*limit, limit, basicSelectDto); if (null == basicVoList || basicVoList.size() == 0) { break; } // System.out.println("查询基础结束" +basicVoList.size()); List updateOrInsertList = new ArrayList<>(5000); System.out.println("开始同步" +basicVoList.size()); for (BasicVo basicVo : basicVoList) { System.out.println("当前病案 " +basicVo.getInpatientNo()); List scanAssortList = this.doSyncFile(basicVo); //2.5数据入库 if (scanAssortList.size() != 0) { List oldScanAssort = scanAssortMapper.getListByPid(basicVo.getPatientId()); //根据pid 查询数据库 根据路径和名称做匹配 如果数据存在需要做幂等 不存在需要做数据更新 List addScanAssortList = this.handleUpdateOrInsert(oldScanAssort,scanAssortList); updateOrInsertList.addAll(addScanAssortList); System.out.println("syncSuccess : " + scanAssortList.size()); // log.info("syncSuccess : " + scanAssortList.size()); } else { log.info(basicVo.getPatientId() + " canFindImage "); } } System.out.println("开始插入数据" +updateOrInsertList.size() ); scanAssortMapper.insertOrUpdateBatch(updateOrInsertList); System.out.println("插入数据结束" ); } },executor); // System.out.println("执行了一个任务" +syncFileDto.getStartDate() +" " +syncFileDto.getEndDate()); return CommonResult.success("同步成功"); } private List handleUpdateOrInsert(List oldScanAssort, List scanAssortList) { //如果没有旧数据 做全量插入 if (ObjectUtil.isEmpty(oldScanAssort)){ return scanAssortList; } List updateOrInsertList = scanAssortList.stream().map(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()); } return m; }).collect(Collectors.toList()); //做新增或者插入 return updateOrInsertList; } private List doSyncFile(BasicVo basicVo) { String[] disDate = dateFormat.format(basicVo.getDisDate()).split("-"); String cyYear = disDate[0]; String cyMonth = disDate[1]; String cyDay = disDate[2]; StringBuilder inpatientNo = new StringBuilder(basicVo.getInpatientNo()); for (int s =inpatientNo.length() ;s<8;s++){ inpatientNo.insert(0, "0"); } String rootDir = "Z:\\" + cyYear + File.separator + cyYear + cyMonth + File.separator + cyYear + cyMonth + cyDay + File.separator + inpatientNo + cyYear + cyMonth + cyDay + File.separator; String outDir = "F:\\lianzhong" + File.separator + cyYear + File.separator + cyMonth + File.separator + cyDay + File.separator + basicVo.getInpatientNo(); String cuid = basicVo.getBColumn5(); List scanAssortList = new ArrayList<>(100); // 2.根据cid查询联众表t_picture 走索引大概零点几秒 List tPictureList = pictureMapper.getPictureInfoByCid(cuid); // 2.1根据病案信息拼接地址 int sort = 0; for (TPicture tpicture : tPictureList) { String picName = tpicture.getPicName().split(".jpg")[0]; String inPutFile = rootDir + picName + ".jp2"; String outFile = outDir + File.separator + picName + ".jpg"; boolean savePicFlag ; boolean rotateFlag ; // 2.2jp2转化jpg 图片通过文件流写到挂在的盘符 savePicFlag = ImageUtils.getInstance().savePic(inPutFile, outFile); if (!savePicFlag){ //需要同步tif文件成jpg过来 savePicFlag = ImageUtils.getInstance().tifToJpg(rootDir + picName + ".tif",outFile); } //需要旋转一下文件 if (tpicture.getRotateDegree()!=0){ rotateFlag = ImageUtils.getInstance().rotateFile(outFile,outFile,tpicture.getRotateDegree()); }else { rotateFlag = true; } // 2.4组合文件信息 ScanAssort scanAssort = new ScanAssort(); 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); scanAssort.setFileSource(2); scanAssort.setFileStorageType(1); scanAssort.setFilePages(1); if (savePicFlag&&rotateFlag){ scanAssort.setCreater("auto2"); }else if (savePicFlag){ scanAssort.setCreater("auto3"); //需要记录创建人为auto3表示同步失败的文件 }else { scanAssort.setCreater("auto4"); } scanAssortList.add(scanAssort); sort+=1; } return scanAssortList; } private BasicSelectDto getBaiscSelectDto(SyncFileDto syncFileDto) { List inpatientNoList = Arrays.asList(syncFileDto.getInpatientNo().split(",")); BasicSelectDto basicSelectDto = new BasicSelectDto(); basicSelectDto.setStartDate(syncFileDto.getStartDate()); basicSelectDto.setEndDate(syncFileDto.getEndDate()); basicSelectDto.setInpatientNoList(inpatientNoList); return basicSelectDto; } }