feat: 处理重复基础数据

jp2demo1.0
wyb 7 months ago
parent c7fefe0ce0
commit 35c4634d4f

@ -130,4 +130,22 @@ public class SyncBasicDataController {
return CommonResult.failed("保存失败!异常处理" + e.getMessage()); return CommonResult.failed("保存失败!异常处理" + e.getMessage());
} }
} }
@ApiOperation("根据 病案号、姓名、出院日期、住院次数 进行筛选数据保留一条")
@GetMapping("/choose")
public CommonResult<?> choose(){
log.info("根据 病案号、姓名、出院日期、住院次数 进行筛选数据保留一条");
try {
syncBasicDataService.choose();
log.info("根据 病案号、姓名、出院日期、住院次数 进行筛选数据保留一条,已完成!");
return CommonResult.success("筛选完成!");
} catch (Exception ex) {
log.error("根据 病案号、姓名、出院日期、住院次数 进行筛选数据保留一条,出现异常!" + ex.getMessage(), ex);
return CommonResult.failed("筛选异常!");
}
}
} }

@ -0,0 +1,32 @@
package com.docus.demo.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author YongBin Wen
* @date 2024/9/6 16:05
*/
@Data
@ApiModel("基础数据选择处理对象")
public class BasicChooseDto {
@ApiModelProperty("病案主键")
private String patientId;
@ApiModelProperty("病案号")
private String inpatientNo;
@ApiModelProperty("患者出院日期 yyyy-MM-dd")
private String disDate;
@ApiModelProperty("患者姓名")
private String name;
@ApiModelProperty("患者姓名")
private Integer admissTimes;
@ApiModelProperty("优先级")
private int priority;
}

@ -49,6 +49,9 @@ public class ScanAssort {
@ApiModelProperty(value = "页数") @ApiModelProperty(value = "页数")
private Integer filePages; private Integer filePages;
@ApiModelProperty(value = "是否作废0未作废")
private Integer isDel;
private String creater; private String creater;
private String createrName; private String createrName;

@ -15,4 +15,6 @@ public interface ISyncBasicDataService {
CommonResult<?> syncLzBasicData(SyncBasicDataDto syncBasicDataDto); CommonResult<?> syncLzBasicData(SyncBasicDataDto syncBasicDataDto);
void scanBasicCorrect(List<BasicCorrectDto> basicCorrectDtos); void scanBasicCorrect(List<BasicCorrectDto> basicCorrectDtos);
void choose();
} }

@ -44,4 +44,10 @@ public interface BasicMapper {
Boolean delTbasicByAdmissId(@Param("admissId")String admissId); Boolean delTbasicByAdmissId(@Param("admissId")String admissId);
int updateScanBasicCorrect(@Param("oldPatId") String oldBasicPatientId, @Param("newPatId") String newPatientId,@Param("ph") String ph); int updateScanBasicCorrect(@Param("oldPatId") String oldBasicPatientId, @Param("newPatId") String newPatientId,@Param("ph") String ph);
int delTbasic(@Param("pidList") List<String> patientIds);
List<Tbasic> getTbasicByInpatientNo(@Param("inpatientNo") String inpatientNo);
List<String> getInpatientNos();
} }

@ -33,5 +33,9 @@ public interface ScanAssortMapper {
int updatePatientId(@Param("oldPatId") String oldBasicPatientId, @Param("newPatId") String newPatientId); int updatePatientId(@Param("oldPatId") String oldBasicPatientId, @Param("newPatId") String newPatientId);
int updatePatientIdById(@Param("ids") List<Long> ids, @Param("newPatId") String newPatientId);
int delScanAssortById(@Param("id") Long id); int delScanAssortById(@Param("id") Long id);
List<ScanAssort> getListByPids(@Param("pidList") List<String> patientIds);
} }

@ -2,11 +2,14 @@ package com.docus.demo.service;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.docus.demo.dto.BasicChooseDto;
import com.docus.demo.dto.BasicCorrectDto; import com.docus.demo.dto.BasicCorrectDto;
import com.docus.demo.dto.SyncBasicDataDto; import com.docus.demo.dto.SyncBasicDataDto;
import com.docus.demo.entity.CommonResult; import com.docus.demo.entity.CommonResult;
import com.docus.demo.entity.ScanAssort;
import com.docus.demo.entity.Tbasic; import com.docus.demo.entity.Tbasic;
import com.docus.demo.entity.TbasicSub; import com.docus.demo.entity.TbasicSub;
import com.docus.demo.entity.sqlserver.CardInfo; import com.docus.demo.entity.sqlserver.CardInfo;
@ -158,10 +161,278 @@ public class SyncBasicDataImpl implements ISyncBasicDataService {
} }
} }
@Override
public void choose() {
int count = 0;
List<String> inpatientNos = basicMapper.getInpatientNos();
log.info("本次筛选病案号数量为:{}", inpatientNos.size());
for (String inpatientNo : inpatientNos) {
choose(inpatientNo);
count++;
log.info("已经筛选病案号:{} 个", count);
}
log.info("本次筛选完成!");
}
/**
*
* / +10
* +4
* +3
* , +2 +1
*
*
*
*/
private void choose(String inpatientNo) {
List<Tbasic> basicList = basicMapper.getTbasicByInpatientNo(inpatientNo);
if (basicList.size() == 1) {
return;
}
Map<String, List<Tbasic>> group = new HashMap<>();
for (Tbasic tbasic : basicList) {
String groupKey = tbasic.getInpatientNo() + "_" + tbasic.getName() + "_" + DateUtil.formatDate(tbasic.getDisDate()) + "_" + tbasic.getAdmissTimes();
List<Tbasic> groupOrDefault = group.getOrDefault(groupKey, new ArrayList<>());
groupOrDefault.add(tbasic);
group.put(groupKey, groupOrDefault);
}
Set<Map.Entry<String, List<Tbasic>>> entries = group.entrySet();
for (Map.Entry<String, List<Tbasic>> entry : entries) {
List<Tbasic> value = entry.getValue();
if (value.size() <= 1) {
continue;
}
groupChoose(value);
}
}
/**
*
*/
private void groupChoose(List<Tbasic> basicList) {
if (basicList.size() <= 1) {
return;
}
List<BasicChooseDto> chooseDtoList = new ArrayList<>();
for (Tbasic basic : basicList) {
BasicChooseDto chooseDto = new BasicChooseDto();
chooseDto.setPatientId(basic.getPatientId());
chooseDto.setName(basic.getName());
chooseDto.setInpatientNo(basic.getInpatientNo());
chooseDto.setAdmissTimes(basic.getAdmissTimes());
chooseDto.setDisDate(DateUtil.formatDate(basic.getDisDate()));
if (StrUtil.isBlank(basic.getPh())) {
chooseDto.setPriority(0);
} else {
chooseDto.setPriority(10);
}
chooseDtoList.add(chooseDto);
}
if (judgeAndProcess(chooseDtoList)) {
return;
}
Map<String, Map<String, List<ScanAssort>>> groupByPatientGroupBySource = new HashMap<>(10);
for (BasicChooseDto basicChooseDto : chooseDtoList) {
List<ScanAssort> assorts = scanAssortMapper.getListByPid(basicChooseDto.getPatientId());
assorts = assorts.stream().filter(f -> {
if (f.getSource() == null) {
f.setSource("unknow");
}
Integer del = 1;
return ObjectUtil.notEqual(del, f.getIsDel());
}).collect(Collectors.toList());
if (CollUtil.isEmpty(assorts)) {
continue;
}
Map<String, List<ScanAssort>> groupBySource = assorts.stream().collect(Collectors.groupingBy(ScanAssort::getSource));
if (groupBySource.containsKey("-1")) {
basicChooseDto.setPriority(basicChooseDto.getPriority() + 4);
}
if (groupBySource.containsKey("lianzhong")) {
basicChooseDto.setPriority(basicChooseDto.getPriority() + 3);
}
groupByPatientGroupBySource.put(basicChooseDto.getPatientId(), groupBySource);
}
if (judgeAndProcess(chooseDtoList)) {
return;
}
int siteMaxSize = 0;
int lianzhongMaxSize = 0;
HashMap<Integer, List<BasicChooseDto>> siteFileCountMap = new HashMap<>();
HashMap<Integer, List<BasicChooseDto>> lianzhongFileCountMap = new HashMap<>();
for (BasicChooseDto chooseDto : chooseDtoList) {
Map<String, List<ScanAssort>> groupBySource = groupByPatientGroupBySource.getOrDefault(chooseDto.getPatientId(), new HashMap<>());
List<ScanAssort> siteScan = groupBySource.getOrDefault("-1", new ArrayList<>());
int siteSize = siteScan.size();
List<ScanAssort> lianzhong = groupBySource.getOrDefault("lianzhong", new ArrayList<>());
int lianzhongSize = lianzhong.size();
List<BasicChooseDto> siteGroup = siteFileCountMap.getOrDefault(siteSize, new ArrayList<>());
siteGroup.add(chooseDto);
List<BasicChooseDto> lianzhongGroup = lianzhongFileCountMap.getOrDefault(lianzhongSize, new ArrayList<>());
lianzhongGroup.add(chooseDto);
siteFileCountMap.put(siteSize, siteGroup);
lianzhongFileCountMap.put(lianzhongSize, lianzhongGroup);
siteMaxSize = Math.max(siteMaxSize, siteSize);
lianzhongMaxSize = Math.max(lianzhongMaxSize, lianzhongSize);
}
List<BasicChooseDto> siteCountChoose = siteFileCountMap.get(siteMaxSize);
List<BasicChooseDto> lianzhongCountChoose = lianzhongFileCountMap.get(lianzhongMaxSize);
for (BasicChooseDto dto : siteCountChoose) {
dto.setPriority(dto.getPriority() + 2);
}
for (BasicChooseDto dto : lianzhongCountChoose) {
dto.setPriority(dto.getPriority() + 1);
}
// 最后无需再判定,直接取最大优先权中的一条
processSelection(chooseDtoList, electedOneData(chooseDtoList));
}
/**
*
*
* @return true
*/
private boolean judgeAndProcess(List<BasicChooseDto> chooseDtoList) {
if (elected(chooseDtoList) && electedOne(chooseDtoList)) {
processSelection(chooseDtoList, electedOneData(chooseDtoList));
return true;
}
return false;
}
/**
*
*
*
*
* @param chooseDtoList
* @param finalElected
*/
private void processSelection(List<BasicChooseDto> chooseDtoList, BasicChooseDto finalElected) {
String selectPatientId = finalElected.getPatientId();
List<String> allPatientIds = chooseDtoList.stream().map(BasicChooseDto::getPatientId).collect(Collectors.toList());
List<ScanAssort> allScanAssorts = scanAssortMapper.getListByPids(allPatientIds);
allScanAssorts = allScanAssorts.stream().filter(f -> {
if (f.getSource() == null) {
f.setSource("unknow");
}
Integer del = 1;
return ObjectUtil.notEqual(del, f.getIsDel());
}).collect(Collectors.toList());
if (CollUtil.isEmpty(allScanAssorts)) {
return;
}
Set<String> allSources = allScanAssorts.stream().map(ScanAssort::getSource).collect(Collectors.toSet());
Set<String> selectPatientSources = allScanAssorts.stream()
.filter(e -> ObjectUtil.equals(selectPatientId, e.getPatientId()))
.map(ScanAssort::getSource)
.collect(Collectors.toSet());
for (String source : allSources) {
if (selectPatientSources.contains(source)) {
continue;
}
transferScanAssortBySource(allScanAssorts, selectPatientId, source);
selectPatientSources.add(source);
}
List<String> notSelectedPids = allPatientIds.stream().filter(e -> !e.equals(selectPatientId)).collect(Collectors.toList());
basicMapper.delTbasic(notSelectedPids);
for (String notSelectedPid : notSelectedPids) {
basicMapper.delTbasicSub(notSelectedPid);
}
}
/**
*
*
* @param allScanAssorts
* @param selectPatientId
* @param source
*/
private void transferScanAssortBySource(List<ScanAssort> allScanAssorts, String selectPatientId, String source) {
// 选择该来源的其他患者中这个来源数量最多的
Map<String, List<ScanAssort>> groupByPatient = allScanAssorts.stream()
.filter(e -> !ObjectUtil.equals(selectPatientId, e.getPatientId()) && ObjectUtil.equals(source, e.getSource()))
.collect(Collectors.groupingBy(ScanAssort::getPatientId));
int maxSize = 0;
String maxSizePatient = null;
Set<Map.Entry<String, List<ScanAssort>>> entries = groupByPatient.entrySet();
for (Map.Entry<String, List<ScanAssort>> entry : entries) {
List<ScanAssort> assorts = entry.getValue();
int size = assorts.size();
if (size > maxSize) {
maxSize = size;
maxSizePatient = assorts.get(0).getPatientId();
}
}
List<ScanAssort> updateScanAssort = groupByPatient.get(maxSizePatient);
List<Long> updateScanAssortIds = updateScanAssort.stream()
.map(ScanAssort::getId)
.collect(Collectors.toList());
scanAssortMapper.updatePatientIdById(updateScanAssortIds, selectPatientId);
}
/**
* ,0
*/
private boolean elected(List<BasicChooseDto> chooseDtoList) {
for (BasicChooseDto dto : chooseDtoList) {
if (dto.getPriority() > 0) {
return true;
}
}
return false;
}
/**
*
*/
private boolean electedOne(List<BasicChooseDto> chooseDtoList) {
List<BasicChooseDto> list = electedMaxPriorityData(chooseDtoList);
return list.size() == 1;
}
/**
*
*/
private BasicChooseDto electedOneData(List<BasicChooseDto> chooseDtoList) {
List<BasicChooseDto> list = electedMaxPriorityData(chooseDtoList);
return list.get(0);
}
/**
*
*/
private List<BasicChooseDto> electedMaxPriorityData(List<BasicChooseDto> chooseDtoList) {
Map<Integer, List<BasicChooseDto>> groupByPriority = chooseDtoList.stream()
.collect(Collectors.groupingBy(BasicChooseDto::getPriority));
int maxPriority = 0;
for (BasicChooseDto chooseDto : chooseDtoList) {
int priority = chooseDto.getPriority();
maxPriority = Math.max(priority, maxPriority);
}
return groupByPriority.get(maxPriority);
}
public static void main(String[] args) { public static void main(String[] args) {
LocalDate startDate = LocalDate.parse("2024-05-06"); LocalDate startDate = LocalDate.parse("2024-05-06");
System.out.println(startDate); System.out.println(startDate);
} }
private List<TbasicSub> getTbasicSubList(List<Tbasic> tbasicList) { private List<TbasicSub> getTbasicSubList(List<Tbasic> tbasicList) {
return tbasicList.stream().map(m -> { return tbasicList.stream().map(m -> {
TbasicSub tbasicSub = new TbasicSub(); TbasicSub tbasicSub = new TbasicSub();
@ -307,7 +578,6 @@ public class SyncBasicDataImpl implements ISyncBasicDataService {
} }
private List<Tbasic> getInsertTbasic(List<Tbasic> oldBasicList, List<CardInfo> cardInfoList) { private List<Tbasic> getInsertTbasic(List<Tbasic> oldBasicList, List<CardInfo> cardInfoList) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
List<CardInfo> cardInfos = cardInfoList.stream().filter(f -> { List<CardInfo> cardInfos = cardInfoList.stream().filter(f -> {

@ -80,6 +80,13 @@
<delete id="delTbasicSub"> <delete id="delTbasicSub">
delete from docus_medicalrecord.t_basic_sub where patient_id=#{patientId} delete from docus_medicalrecord.t_basic_sub where patient_id=#{patientId}
</delete> </delete>
<delete id="delTbasic">
delete from docus_medicalrecord.t_basic
where patient_id in
<foreach collection="pidList" item="pid" separator="," open="(" close=")">
#{pid}
</foreach>
</delete>
<select id="getBasicVoList" resultType="com.docus.demo.vo.BasicVo"> <select id="getBasicVoList" resultType="com.docus.demo.vo.BasicVo">
@ -189,6 +196,27 @@
from docus_medicalrecord.t_basic from docus_medicalrecord.t_basic
where patient_id = #{patientId} where patient_id = #{patientId}
</select> </select>
<select id="getTbasicByInpatientNo" resultType="com.docus.demo.entity.Tbasic">
SELECT
patient_id,
admiss_times,
inpatient_no,
admiss_date,
`name`,
dis_date,
ph
FROM
docus_medicalrecord.t_basic
where
inpatient_no = #{inpatientNo}
</select>
<select id="getInpatientNos" resultType="java.lang.String">
SELECT
inpatient_no
FROM
docus_medicalrecord.t_basic
group by inpatient_no
</select>
</mapper> </mapper>

@ -47,6 +47,13 @@
<update id="updatePatientId"> <update id="updatePatientId">
update docus_archivefile.t_scan_assort set patient_id=#{newPatId} where patient_id=#{oldPatId} update docus_archivefile.t_scan_assort set patient_id=#{newPatId} where patient_id=#{oldPatId}
</update> </update>
<update id="updatePatientIdById">
update docus_archivefile.t_scan_assort set patient_id=#{newPatId}
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</update>
<delete id="deleteByPid"> <delete id="deleteByPid">
delete FROM docus_archivefile.t_scan_assort delete FROM docus_archivefile.t_scan_assort
where patient_id in where patient_id in
@ -74,7 +81,9 @@
file_pages, file_pages,
creater, creater,
create_time, create_time,
sort sort,
is_del,
source
FROM docus_archivefile.t_scan_assort FROM docus_archivefile.t_scan_assort
WHERE patient_id = #{pid} WHERE patient_id = #{pid}
</select> </select>
@ -90,7 +99,9 @@
file_pages, file_pages,
creater, creater,
create_time, create_time,
sort sort,
is_del,
source
FROM docus_archivefile.t_scan_assort FROM docus_archivefile.t_scan_assort
WHERE assort_id = #{assortId} and patient_id = #{pid} and source='jy' WHERE assort_id = #{assortId} and patient_id = #{pid} and source='jy'
@ -98,5 +109,26 @@
<select id="getScanAssort" resultType="com.docus.demo.entity.ScanAssort"> <select id="getScanAssort" resultType="com.docus.demo.entity.ScanAssort">
SELECT * FROM docus_archivefile.t_scan_assort WHERE patient_id=#{patientId} and source=#{source} SELECT * FROM docus_archivefile.t_scan_assort WHERE patient_id=#{patientId} and source=#{source}
</select> </select>
<select id="getListByPids" resultType="com.docus.demo.entity.ScanAssort">
SELECT id,
patient_id,
assort_id,
file_title,
image_path,
scan_page,
file_source,
file_storage_type,
file_pages,
creater,
create_time,
sort,
is_del,
source
FROM docus_archivefile.t_scan_assort
where patient_id in
<foreach collection="pidList" item="pid" separator="," open="(" close=")">
#{pid}
</foreach>
</select>
</mapper> </mapper>
Loading…
Cancel
Save