从联众同步基础数据逻辑

main
zhanglb 2 years ago
parent 2ee02fe4e8
commit aec807a51d

@ -24,13 +24,19 @@ public class SyncBasicDataController {
@Autowired
private ISyncBasicFileService syncBasicFileService;
@ApiOperation("同步基础数据")
@ApiOperation("省厅-同步基础数据")
@PostMapping("/syncBasicData")
public CommonResult<?> syncBasicData(@RequestBody SyncBasicDataDto syncBasicDataDto){
return syncBasicDataService.syncBasicData(syncBasicDataDto);
}
@ApiOperation("同步基础数据")
@ApiOperation("联众-同步基础数据")
@PostMapping("/syncLzBasicData")
public CommonResult<?> syncLzBasicData(@RequestBody SyncBasicDataDto syncBasicDataDto){
return syncBasicDataService.syncLzBasicData(syncBasicDataDto);
}
@ApiOperation("同步文件数据")
@PostMapping("/syncBasicFile")
public CommonResult<?> syncBasicFile(@RequestBody SyncFileDto syncFileDto){
return syncBasicFileService.syncBasicFile(syncFileDto);

@ -5,7 +5,9 @@ import lombok.Data;
@Data
public class SyncBasicDataDto {
private String startDate;
private String endDate;
private int limit;
}

@ -0,0 +1,40 @@
package com.docus.demo.entity.sqlserver;
import lombok.Data;
import java.util.Date;
@Data
public class CardInfo {
private long id ;
private Integer PatNum;
private String PatNo;
private String PatName;
private String PatSex;
private Integer PatAge;
/**身份证**/
private String PatCiticard;
private String UnitTele;
private Date InDate;
private String InDeptCode;
private String InDeptName;
private Date OutDate;
private String OutDeptCode;
private String OutDeptName;
private String OperIcpm1;
private String OperName1;
private String IcdeCode11;
private String IcdeName11;
private String cuid;
}

@ -8,4 +8,6 @@ public interface ISyncBasicDataService {
CommonResult<?> syncBasicData(SyncBasicDataDto syncBasicDataDto);
CommonResult<?> syncLzBasicData(SyncBasicDataDto syncBasicDataDto);
}

@ -0,0 +1,18 @@
package com.docus.demo.mapper.sqlserver;
import com.docus.demo.dto.SyncBasicDataDto;
import com.docus.demo.entity.sqlserver.CardInfo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface TcardMapper {
List<CardInfo> getCardInfo(@Param("pageStart") int pageStart,
@Param("pageEnd") int pageEnd,
@Param("dto") SyncBasicDataDto syncBasicDataDto);
}

@ -5,11 +5,13 @@ import cn.hutool.core.util.ObjectUtil;
import com.docus.demo.dto.SyncBasicDataDto;
import com.docus.demo.entity.CommonResult;
import com.docus.demo.entity.Tbasic;
import com.docus.demo.entity.sqlserver.CardInfo;
import com.docus.demo.entity.sqlserver1.Tdiagnose;
import com.docus.demo.entity.sqlserver1.Toperation;
import com.docus.demo.entity.sqlserver1.Tpatientvisit;
import com.docus.demo.facade.ISyncBasicDataService;
import com.docus.demo.mapper.mysql.BasicMapper;
import com.docus.demo.mapper.sqlserver.TcardMapper;
import com.docus.demo.mapper.sqlserver1.PaintVisitMapper;
import com.docus.demo.utils.SnowflakeIdWorker;
import org.springframework.beans.factory.annotation.Autowired;
@ -26,7 +28,8 @@ public class SyncBasicDataImpl implements ISyncBasicDataService {
@Autowired
private PaintVisitMapper paintVisitMapper;
@Autowired
private TcardMapper tcardMapper;
@Override
@ -55,6 +58,7 @@ public class SyncBasicDataImpl implements ISyncBasicDataService {
return CommonResult.success("同步成功");
}
private List<Tbasic> getTbasicList(List<Tbasic> oldBasicList,List<Tpatientvisit> tpatientvisitList, List<Tdiagnose> tdiagnoses, List<Toperation> toperations) {
return tpatientvisitList.stream()
@ -122,4 +126,76 @@ public class SyncBasicDataImpl implements ISyncBasicDataService {
return tbasic;
}).collect(Collectors.toList());
}
@Override
public CommonResult<?> syncLzBasicData(SyncBasicDataDto syncBasicDataDto) {
//页码
int current;
//每页1000条数据
int limit = syncBasicDataDto.getLimit();
List<CardInfo> cardInfoList;
for (current = 1; ; current++) {
cardInfoList = tcardMapper.getCardInfo((current-1)*limit, limit,syncBasicDataDto);
if (null == cardInfoList || cardInfoList.size() == 0) {
break;
}
List<String> fprnList = cardInfoList.stream().map(CardInfo::getPatNo).collect(Collectors.toList());
//数据map转换
List<Tbasic> oldBasicList = basicMapper.getOldBasicList(fprnList,syncBasicDataDto);
List<Tbasic> tbasicList = this.getInsertTbasic(oldBasicList,cardInfoList);
if (ObjectUtil.isNotEmpty(tbasicList)){
//判断数据量 如果文件数据大于五百条 需要做拆分分批次插入
int batchSize = 1000;
// 拆分列表
for (int i = 0; i < tbasicList.size(); i += batchSize) {
int endIndex = Math.min(i + batchSize, tbasicList.size());
List<Tbasic> sublist = tbasicList.subList(i, endIndex);
//数据入库
basicMapper.insertOrUpdateByid(sublist);
}
}
}
return CommonResult.success("同步成功");
}
private List<Tbasic> getInsertTbasic(List<Tbasic> oldBasicList, List<CardInfo> cardInfoList) {
return cardInfoList.stream().filter(f->{
String pno = f.getPatNo();
String name = f.getPatName();
Integer pNum = f.getPatNum();
Date date = f.getOutDate();
Tbasic tbasic = oldBasicList.stream().filter(o->
ObjectUtil.equal(o.getInpatientNo(),pno)
&&ObjectUtil.equal(name,o.getName())
&&ObjectUtil.equal(pNum,o.getAdmissTimes())
&&ObjectUtil.equal(date,o.getDisDate()))
.findAny()
.orElse(null);
return tbasic==null;
}).map(m->{
//根据病案号 名称 住院次数 出院时间 去重
Tbasic tbasic = new Tbasic();
tbasic.setPatientId(String.valueOf(SnowflakeIdWorker.idWorker.nextId()));
tbasic.setAdmissTimes(m.getPatNum());
tbasic.setInpatientNo(m.getPatNo());
tbasic.setAdmissId(m.getPatNo());
tbasic.setName(m.getPatName());
tbasic.setSex(m.getPatSex());
tbasic.setAge(m.getPatAge());
tbasic.setIdCard(m.getPatCiticard());
tbasic.setAdmissDate(m.getInDate());
tbasic.setAdmissDept(m.getInDeptCode());
tbasic.setAdmissDeptName(m.getInDeptName());
tbasic.setDisDate(m.getOutDate());
tbasic.setDisDept(m.getOutDeptCode());
tbasic.setDisDeptName(m.getOutDeptName());
tbasic.setMainDiagName(m.getIcdeName11());
tbasic.setMainDiagCode(m.getIcdeCode11());
tbasic.setMainOperateName(m.getOperName1());
tbasic.setMainOperateCode(m.getOperIcpm1());
return tbasic;
}).collect(Collectors.toList());
}
}

@ -50,47 +50,38 @@ public class SyncBasicFileImpl implements ISyncBasicFileService {
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<BasicVo> 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<ScanAssort> updateOrInsertList = new ArrayList<>(5000);
System.out.println("开始同步" +basicVoList.size());
// List<ScanAssort> updateOrInsertList = new ArrayList<>(5000);
for (BasicVo basicVo : basicVoList) {
System.out.println("当前病案 " +basicVo.getInpatientNo());
log.info("开始同步"+basicVo.getInpatientNo());
List<ScanAssort> scanAssortList = this.doSyncFile(basicVo);
//2.5数据入库
if (scanAssortList.size() != 0) {
List<ScanAssort> oldScanAssort = scanAssortMapper.getListByPid(basicVo.getPatientId());
//根据pid 查询数据库 根据路径和名称做匹配 如果数据存在需要做幂等 不存在需要做数据更新
List<ScanAssort> 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 ");
}
// if (scanAssortList.size() != 0) {
// List<ScanAssort> oldScanAssort = scanAssortMapper.getListByPid(basicVo.getPatientId());
// //根据pid 查询数据库 根据路径和名称做匹配 如果数据存在需要做幂等 不存在需要做数据更新
// List<ScanAssort> addScanAssortList = this.handleUpdateOrInsert(oldScanAssort,scanAssortList);
// updateOrInsertList.addAll(addScanAssortList);
// } else {
// log.info(basicVo.getPatientId() + " canFindImage ");
// }
log.info("结束同步"+basicVo.getInpatientNo());
}
System.out.println("开始插入数据" +updateOrInsertList.size() );
scanAssortMapper.insertOrUpdateBatch(updateOrInsertList);
System.out.println("插入数据结束" );
// scanAssortMapper.insertOrUpdateBatch(updateOrInsertList);
}
},executor);
// System.out.println("执行了一个任务" +syncFileDto.getStartDate() +" " +syncFileDto.getEndDate());
return CommonResult.success("同步成功");
@ -152,20 +143,24 @@ public class SyncBasicFileImpl implements ISyncBasicFileService {
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;
File file = new File(inPutFile);
if (!file.exists()){
log.info(basicVo.getInpatientNo()+"文件未找到"+inPutFile);
}
// 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组合文件信息
@ -183,14 +178,14 @@ public class SyncBasicFileImpl implements ISyncBasicFileService {
scanAssort.setFilePages(1);
if (savePicFlag&&rotateFlag){
scanAssort.setCreater("auto2");
}else if (savePicFlag){
scanAssort.setCreater("auto3");
//需要记录创建人为auto3表示同步失败的文件
}else {
scanAssort.setCreater("auto4");
}
// if (savePicFlag&&rotateFlag){
// scanAssort.setCreater("auto2");
// }else if (savePicFlag){
// scanAssort.setCreater("auto3");
// //需要记录创建人为auto3表示同步失败的文件
// }else {
// scanAssort.setCreater("auto4");
// }
@ -213,4 +208,47 @@ public class SyncBasicFileImpl implements ISyncBasicFileService {
return basicSelectDto;
}
private String getRootDir(BasicVo basicInfo, String cyYear, String cyMonth, String cyDay) {
String inpatientNo = basicInfo.getInpatientNo().trim();
String rootDir = "";
rootDir = "Z:\\"
+ 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 = "Z:\\"
+ 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 rootDir;
}
}

@ -7,6 +7,7 @@ import leadtools.codecs.CodecsLoadByteOrder;
import leadtools.codecs.CodecsSavePageMode;
import leadtools.codecs.RasterCodecs;
import leadtools.demos.DemoUtilities;
import lombok.extern.slf4j.Slf4j;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
@ -16,6 +17,7 @@ import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.*;
@Slf4j
public class ImageUtils {
private static final ImageUtils instance = new ImageUtils();
@ -132,12 +134,11 @@ public class ImageUtils {
OutputStream outputStream = new FileOutputStream(outFile);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
System.out.println("成功将TIFF文件的字节码写入到新文件");
log.info(inPutFile + "成功将TIFF文件的字节码写入到新文件 " +outFile);
return true;
} catch (IOException e) {
e.printStackTrace();
}
@ -246,11 +247,11 @@ public class ImageUtils {
// Save image
// System.out.println("Save image...");
rasterCodecs.save(rasterImage, demoData.outFilePath, RasterImageFormat.valueOf(demoData.outputFormat.toString()), demoData.outputBPP, 1, -1, 1, CodecsSavePageMode.OVERWRITE);
System.out.println("Image saved successfully here: " + demoData.outFilePath);
log.info("Image saved successfully here: " + demoData.outFilePath);
return true;
} catch (Exception e) {
// System.out.println(e.getMessage());
return false;
} finally {
// Dispose the raster codecs
if (rasterCodecs != null)
@ -262,8 +263,7 @@ public class ImageUtils {
}
} catch (Exception ex) {
// System.out.println("Error " + ex.getMessage());
ex.printStackTrace();
log.info(ex.getMessage());
}
return false;
@ -285,4 +285,10 @@ public class ImageUtils {
}
// public static void main(String[] args) {
// ImageUtils imageUtils = new ImageUtils();
//// imageUtils.savePic("C:\\Users\\Administrator\\Desktop\\HNSET0001.jp2.jp2","C:\\Users\\Administrator\\Desktop\\HNSET0001.jp2.jpg");
// imageUtils.tifToJpg("C:\\Users\\Administrator\\Desktop\\HNSET0001.tif","C:\\Users\\Administrator\\Desktop\\HNSET0001.jpg");
// imageUtils.rotateFile("C:\\Users\\Administrator\\Desktop\\HNSET0001.jp2.jpg","C:\\Users\\Administrator\\Desktop\\HNSET0001.jp2.jpg",90);
// }
}

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">
<contextName>docus-server-fistpage</contextName>
<property name="log.path" value="logs/logback"/>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%contextName] [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<!-- 指定日志输出格式 -->
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%X{traceId}] [%L] [%-5p] %m%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 指定收集策略:滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--指定生成日志保存地址 -->
<fileNamePattern>${log.path}%d.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>500MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
</appender>
<appender name="external-interface" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<!-- 指定日志输出格式 -->
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%X{traceId}] [%L] [%-5p] %m%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 指定收集策略:滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--指定生成日志保存地址 -->
<fileNamePattern>${log.path}external%d.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>500MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
</appender>
<logger name="com.docus.services.system.service.ClientGetBasicServiceImpl" level="DEBUG" additivity="false">
<appender-ref ref="external-interface" />
</logger>
<root level="INFO">
<appender-ref ref="file"/>
<appender-ref ref="console"/>
</root>
<springProfile name="test|prod">
</springProfile>
<!-- 监控sql日志输出-->
<!-- 如想看到表格数据将OFF改为INFO -->
<logger name="jdbc.resultsettable" level="OFF" additivity="false">
<appender-ref ref="console"/>
</logger>
<!-- 包含 SQL 语句实际的执行时间 及sql语句与jdbc.sqlonly功能重复 -->
<logger name="jdbc.sqltiming" level="OFF" additivity="false">
<appender-ref ref="file"/>
</logger>
<!-- 仅仅记录 SQL 语句,会将占位符替换为实际的参数-->
<logger name="jdbc.sqlonly" level="OFF" additivity="false">
<appender-ref ref="console"/>
</logger>
<!-- 包含 ResultSet 的信息,输出篇幅较长 -->
<logger name="jdbc.resultset" level="OFF" additivity="false">
<appender-ref ref="console"/>
</logger>
<!-- 输出了 Connection 的 open、close 等信息 -->
<logger name="jdbc.connection" level="OFF" additivity="false">
<appender-ref ref="console"/>
</logger>
<!-- 除了 ResultSet 之外的所有JDBC调用信息篇幅较长 -->
<logger name="jdbc.audit" level="OFF" additivity="false">
<appender-ref ref="console"/>
</logger>
</configuration>

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.docus.demo.mapper.sqlserver.TcardMapper">
<select id="getCardInfo" resultType="com.docus.demo.entity.sqlserver.CardInfo">
SELECT *
from (
SELECT row_number() over(order by id ) as num ,
id,
PatNum,
PatNo,
PatName,
PatSex,
PatAge,
PatCiticard,
UnitTele,
InDate,
InDeptCode,
InDeptName,
OutDate,
OutDeptCode,
OutDeptName,
cuid
FROM T_card_info
WHERE OutDate &gt;= #{dto.startDate}
AND OutDate &lt;= #{dto.endDate}
) as t2
where t2.num &gt;= #{pageStart}
and t2.num &lt;= {pageEnd}
</select>
</mapper>
Loading…
Cancel
Save