| | |
| | | package com.ruoyi.quartz.service.impl; |
| | | |
| | | import com.ruoyi.othervisit.api.OtherVisitFacade; |
| | | import com.ruoyi.inhospvisit.api.InhospVisitFacade; |
| | | import com.google.gson.Gson; |
| | | import com.ruoyi.common.core.domain.entity.SysDept; |
| | | import com.ruoyi.common.core.domain.entity.SysUser; |
| | | import com.ruoyi.common.core.domain.entity.SysUserDept; |
| | | import com.ruoyi.common.core.redis.RedisCache; |
| | | import com.ruoyi.common.utils.ArrayListUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.quartz.mapper.CollectHISMapper; |
| | | import com.ruoyi.quartz.service.ICollectHISService; |
| | | import com.smartor.common.SpecificArchiveConstants; |
| | | import com.smartor.domain.*; |
| | | import com.smartor.mapper.*; |
| | | import com.smartor.service.IPatMedOuthospService; |
| | | import com.smartor.service.IPatSpecificArchiveGenerateService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.apache.commons.lang3.ArrayUtils; |
| | | import org.apache.commons.lang3.ObjectUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneId; |
| | | import java.util.*; |
| | | import java.util.concurrent.atomic.AtomicBoolean; |
| | | import java.util.stream.Collectors; |
| | | import java.util.stream.Stream; |
| | | |
| | | import com.ruoyi.othervisit.domain.PatMedOperationItem; |
| | | import com.ruoyi.outpatientvisit.mapper.PatMedOuthospMapper; |
| | | import com.ruoyi.othervisit.domain.PatMedOperation; |
| | | import com.ruoyi.outpatientvisit.domain.PatMedOuthosp; |
| | | import com.ruoyi.outpatientvisit.domain.PatMedOuthospQueryReq; |
| | | import com.ruoyi.inhospvisit.domain.PatMedInhosp; |
| | | import com.ruoyi.common.core.domain.entity.PatArchive; |
| | | import com.ruoyi.task.domain.entity.ServiceSubtaskEntity; |
| | | import com.ruoyi.task.domain.ServiceSubtask; |
| | | import com.ruoyi.task.mapper.ServiceSubtaskMapper; |
| | | import com.ruoyi.patarchive.mapper.PatArchiveMapper; |
| | | import com.ruoyi.common.core.domain.entity.Icd10; |
| | | import com.ruoyi.common.mapper.Icd10Mapper; |
| | | import com.ruoyi.system.mapper.ext.SysUser2Mapper; |
| | | import com.ruoyi.system.mapper.ext.SysDept2Mapper; |
| | | import com.ruoyi.system.mapper.ext.SysUserDeptMapper; |
| | | import com.ruoyi.patarchive.mapper.ShardingMapper; |
| | | import com.ruoyi.datacollection.domain.HnDataGatherVO; |
| | | @Slf4j |
| | | @Service |
| | | public class CollectHISServiceImpl implements ICollectHISService { |
| | | @Autowired |
| | | private CollectHISMapper chMapper; |
| | | |
| | | /** |
| | | * 手术数据一律经 ruoyi-othervisit 的门面取用(跨模块数据访问原则)。 |
| | | */ |
| | | @Autowired |
| | | private OtherVisitFacade otherVisitFacade; |
| | | |
| | | @Autowired |
| | | private SysUser2Mapper sysUser2Mapper; |
| | | |
| | | @Autowired |
| | | private SysUserRole2Mapper sysUserRoleMapper; |
| | | private IPatMedOuthospService patMedOuthospService; |
| | | |
| | | @Autowired |
| | | private IPatSpecificArchiveGenerateService patSpecificArchiveGenerateService; |
| | | |
| | | @Autowired |
| | | private SysDept2Mapper sysDept2Mapper; |
| | |
| | | private PatMedOuthospMapper patMedOuthospMapper; |
| | | |
| | | @Autowired |
| | | private PatMedInhospMapper patMedInhospMapper; |
| | | private InhospVisitFacade inhospVisitFacade; |
| | | |
| | | @Autowired |
| | | private PatArchiveMapper patArchiveMapper; |
| | | |
| | | @Autowired |
| | | private ServiceSubtaskMapper serviceSubtaskMapper; |
| | | |
| | | @Autowired |
| | | private ThreadPoolTaskExecutor taskExecutor; |
| | |
| | | |
| | | @Autowired |
| | | private UtilsMapper utilsMapper; |
| | | |
| | | @Autowired |
| | | private RedisCache redisCache; |
| | | |
| | | /** |
| | | * 用户同步任务运行标记,避免重复点击/重复调用并发跑全量同步 |
| | | */ |
| | | private final AtomicBoolean userSyncRunning = new AtomicBoolean(false); |
| | | |
| | | private static final long SHARDING_THRESHOLD = 5_000_000L; |
| | | private static final String PAT_ARCHIVE_TABLE = "pat_archive"; |
| | |
| | | Integer count = 0; |
| | | List<Map<String, Object>> syncList = utilsMapper.getList("SELECT id,syncName,DATE_FORMAT(ADDDATE(startTime, INTERVAL -1 MINUTE), '%Y-%m-%d %H:%i:%s') startTime FROM sys_sync_time where state=0"); |
| | | if (syncList.size() > 0) { |
| | | String endTime = chMapper.getSqlString("select sysdate from healthy_inhosp where rownum=1"); |
| | | String endTime = chMapper.getSqlString("select (sysdate-1) as endtime from healthy_inhosp where rownum=1"); |
| | | //同步患者基本信息 |
| | | // List<Map<String, Object>> syncTemp = syncList.stream().filter(row -> row.get("syncName").equals("pat_archive")).collect(Collectors.toList()); |
| | | // if (syncTemp.size() > 0) { |
| | |
| | | //同步住院病人信息 |
| | | List<Map<String, Object>> syncTemp = syncList.stream().filter(row -> row.get("syncName").equals("pat_med_inhosp")).collect(Collectors.toList()); |
| | | if (syncTemp.size() > 0) { |
| | | log.info("startTime:" + syncTemp.get(0).get("startTime") + ", endTime: ", endTime); |
| | | count += syncMedInhosp(syncTemp.get(0).get("startTime") + "", endTime); |
| | | utilsMapper.updateSql("update sys_sync_time set startTime='" + endTime + "' where syncName='pat_med_inhosp' "); |
| | | } |
| | |
| | | utilsMapper.updateSql("update sys_sync_time set startTime='" + endTime + "' where syncName='pat_med_outhosp' "); |
| | | } |
| | | |
| | | //同步手术信息 |
| | | syncTemp = syncList.stream().filter(row -> row.get("syncName").equals("pat_med_operation")).collect(Collectors.toList()); |
| | | if (syncTemp.size() > 0) { |
| | | count += syncOper(syncTemp.get(0).get("startTime") + "", endTime); |
| | | utilsMapper.updateSql("update sys_sync_time set startTime='" + endTime + "' where syncName='pat_med_operation' "); |
| | | } |
| | | |
| | | } else { |
| | | log.info("同步任务时间sys_sync_time表中没有需要同步的任务"); |
| | |
| | | * @param |
| | | * @return |
| | | */ |
| | | private Integer syncMedInhosp(String startTime, String endTime) { |
| | | @Override |
| | | public Integer syncMedInhosp(String startTime, String endTime) { |
| | | Integer count = 0; |
| | | PatMedInhosp patMedInhosp = new PatMedInhosp(); |
| | | patMedInhosp.setLastStartTime(startTime); |
| | |
| | | //同步出入院 |
| | | PatMedInhosp pmi = new PatMedInhosp(); |
| | | pmi.setSerialnum(pm.getSerialnum()); |
| | | List<PatMedInhosp> patMedInhospList1 = patMedInhospMapper.selectPatMedInhospListBySerialnum(pmi); |
| | | List<PatMedInhosp> patMedInhospList1 = inhospVisitFacade.selectPatMedInhospListBySerialnum(pmi); |
| | | if (patMedInhospList1.size() == 0) { |
| | | pm.setCreateTime(new Date()); |
| | | //市一 院区id对应orgid,机构id为默认的1 |
| | |
| | | pm.setCampusid(pm.getOrgid()); |
| | | pm.setOrgid("1"); |
| | | } |
| | | count += patMedInhospMapper.insertPatMedInhosp(pm); |
| | | count += inhospVisitFacade.insertPatMedInhosp(pm); |
| | | } else { |
| | | pm.setInhospid(patMedInhospList1.get(0).getInhospid()); |
| | | pm.setUpdateTime(new Date()); |
| | |
| | | pm.setCampusid(pm.getOrgid()); |
| | | pm.setOrgid("1"); |
| | | } |
| | | count += patMedInhospMapper.updatePatMedInhosp(pm); |
| | | count += inhospVisitFacade.updatePatMedInhosp(pm); |
| | | } |
| | | } catch (Exception ex) { |
| | | log.info("同步出入院:" + ex.getMessage()); |
| | |
| | | * @return |
| | | */ |
| | | private Integer syncOuthosp(String startTime, String endTime) { |
| | | return syncOuthosp(startTime, endTime, null, false); |
| | | } |
| | | |
| | | /** |
| | | * 同步门诊信息。 |
| | | * |
| | | * @param startTime 开始时间 |
| | | * @param endTime 结束时间 |
| | | * @param orgid 机构ID,为空时同步全部机构 |
| | | * @param byAdmitDate true=按就诊日期过滤(补采);false=按最后更新时间增量同步 |
| | | */ |
| | | private Integer syncOuthosp(String startTime, String endTime, String orgid, boolean byAdmitDate) { |
| | | Integer count = 0; |
| | | PatMedOuthosp patMedOuthosp = new PatMedOuthosp(); |
| | | patMedOuthosp.setLastStartTime(startTime); |
| | | patMedOuthosp.setLastEndTime(endTime); |
| | | if (byAdmitDate) { |
| | | patMedOuthosp.setBeginTime(parseDateTime(startTime)); |
| | | patMedOuthosp.setEndTime(parseDateTime(endTime)); |
| | | } else { |
| | | patMedOuthosp.setLastStartTime(startTime); |
| | | patMedOuthosp.setLastEndTime(endTime); |
| | | } |
| | | patMedOuthosp.setOrgid(orgid); |
| | | List<PatMedOuthosp> patMedOuthosps = chMapper.selectPatMedOuthospList(patMedOuthosp); |
| | | log.info("同步门诊信息数量" + patMedOuthosps.size()); |
| | | log.info("同步门诊信息数量:{},orgid={},byAdmitDate={}", patMedOuthosps.size(), orgid, byAdmitDate); |
| | | for (PatMedOuthosp patMedOuthosp1 : patMedOuthosps) { |
| | | // 按机构补采时,HIS 视图未返回 orgid 的记录补上查询条件中的机构 |
| | | if (StringUtils.isEmpty(patMedOuthosp1.getOrgid()) && StringUtils.isNotEmpty(orgid)) { |
| | | patMedOuthosp1.setOrgid(orgid); |
| | | } |
| | | PatArchive localArchive = null; |
| | | try { |
| | | //患者基本信息 |
| | | PatArchive patArchive = new PatArchive(); |
| | |
| | | pa1.setPatientno(patMedOuthosp1.getPatno()); |
| | | List<PatArchive> patArchives1 = patArchiveMapper.selectPatArchiveList(pa1); |
| | | if (CollectionUtils.isNotEmpty(patArchives1)) { |
| | | patArchives.get(0).setId(patArchives1.get(0).getId()); |
| | | localArchive = patArchives1.get(0); |
| | | patArchives.get(0).setId(localArchive.getId()); |
| | | patArchives.get(0).setUpdateTime(new Date()); |
| | | count += patArchiveMapper.updatePatArchive(patArchives.get(0)); |
| | | } else { |
| | | patArchives.get(0).setCreateTime(new Date()); |
| | | count += patArchiveMapper.insertPatArchiveSingle(patArchives.get(0)); |
| | | |
| | | localArchive = patArchives.get(0); |
| | | } |
| | | } |
| | | } catch (Exception ex) { |
| | | log.info("同患者基本信息:" + ex.getMessage()); |
| | | } |
| | | |
| | | // HIS 患者信息缺失时,仍按患者编号回查本地档案 |
| | | if (localArchive == null && StringUtils.isNotEmpty(patMedOuthosp1.getPatno())) { |
| | | try { |
| | | PatArchive localQuery = new PatArchive(); |
| | | localQuery.setPatientno(patMedOuthosp1.getPatno()); |
| | | List<PatArchive> localArchives = patArchiveMapper.selectPatArchiveList(localQuery); |
| | | if (CollectionUtils.isNotEmpty(localArchives)) { |
| | | localArchive = localArchives.get(0); |
| | | } |
| | | } catch (Exception ex) { |
| | | log.info("回查本地患者档案失败:" + ex.getMessage()); |
| | | } |
| | | } |
| | | |
| | | try { |
| | | PatMedOuthosp patMedOuthospTemp = new PatMedOuthosp(); |
| | | patMedOuthospTemp.setSerialnum(patMedOuthosp1.getSerialnum()); |
| | | List<PatMedOuthosp> patMedOuthospsTemp = chMapper.selectPatMedOuthospList(patMedOuthosp); |
| | | if (patMedOuthospsTemp.size() > 0) { |
| | | if (localArchive != null && localArchive.getId() != null) { |
| | | patMedOuthosp1.setPatid(localArchive.getId()); |
| | | } |
| | | PatMedOuthosp localOuthosp = null; |
| | | try { |
| | | localOuthosp = findLocalOuthosp(patMedOuthosp1); |
| | | } catch (Exception e) { |
| | | log.warn("回查本地门诊记录失败,按新增处理,serialnum={}", patMedOuthosp1.getSerialnum(), e); |
| | | } |
| | | if (localOuthosp != null) { |
| | | patMedOuthosp1.setUpdateTime(new Date()); |
| | | patMedOuthosp1.setId(patMedOuthospsTemp.get(0).getId()); |
| | | patMedOuthosp1.setId(localOuthosp.getId()); |
| | | //市一 院区id对应orgid,机构id为默认的1 |
| | | if(active.equals("hzszlyy")) { |
| | | patMedOuthosp1.setCampusid(patMedOuthosp1.getOrgid()); |
| | | patMedOuthosp1.setOrgid("1"); |
| | | } |
| | | count += patMedOuthospMapper.updatePatMedOuthosp(patMedOuthosp1); |
| | | count += patMedOuthospService.updatePatMedOuthosp(patMedOuthosp1); |
| | | } else { |
| | | patMedOuthosp1.setCreateTime(new Date()); |
| | | //市一 院区id对应orgid,机构id为默认的1 |
| | |
| | | patMedOuthosp1.setCampusid(patMedOuthosp1.getOrgid()); |
| | | patMedOuthosp1.setOrgid("1"); |
| | | } |
| | | count += patMedOuthospMapper.insertPatMedOuthosp(patMedOuthosp1); |
| | | count += patMedOuthospService.insertPatMedOuthosp(patMedOuthosp1); |
| | | } |
| | | generateSpecificArchive(patMedOuthosp1, localArchive); |
| | | } catch (Exception ex) { |
| | | log.info("同步出入院:" + ex.getMessage()); |
| | | log.info("同步门诊信息:" + ex.getMessage()); |
| | | } |
| | | } |
| | | return count; |
| | | } |
| | | |
| | | /** |
| | | * 回查本地门诊记录,避免重复采集时插入重复数据。 |
| | | */ |
| | | private PatMedOuthosp findLocalOuthosp(PatMedOuthosp record) { |
| | | if (StringUtils.isEmpty(record.getSerialnum()) && StringUtils.isEmpty(record.getOuthospno())) { |
| | | return null; |
| | | } |
| | | PatMedOuthospQueryReq req = new PatMedOuthospQueryReq(); |
| | | req.setSerialnum(record.getSerialnum()); |
| | | req.setOuthospno(record.getOuthospno()); |
| | | req.setOrgid(record.getOrgid()); |
| | | List<PatMedOuthosp> localList = patMedOuthospMapper.callSpQueryOuthosp(req); |
| | | return CollectionUtils.isNotEmpty(localList) ? localList.get(0) : null; |
| | | } |
| | | |
| | | /** |
| | | * 门诊接诊完成记录采集后生成专科档案(仅丽水市妇幼保健院生效)。 |
| | | */ |
| | | private void generateSpecificArchive(PatMedOuthosp patMedOuthosp, PatArchive patArchive) { |
| | | if (!SpecificArchiveConstants.LISHUI_MCH_ORG_ID.equals(patMedOuthosp.getOrgid())) { |
| | | return; |
| | | } |
| | | try { |
| | | int generated = patSpecificArchiveGenerateService.generateByOuthosp(patMedOuthosp, patArchive); |
| | | if (generated > 0) { |
| | | log.info("门诊接诊完成记录生成专科档案成功,outhospno={},生成数量={}", |
| | | patMedOuthosp.getOuthospno(), generated); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("门诊接诊完成记录生成专科档案失败,outhospno={}", patMedOuthosp.getOuthospno(), e); |
| | | } |
| | | } |
| | | |
| | | private Date parseDateTime(String value) { |
| | | if (StringUtils.isEmpty(value)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value); |
| | | } catch (Exception e) { |
| | | try { |
| | | return new SimpleDateFormat("yyyy-MM-dd").parse(value); |
| | | } catch (Exception ex) { |
| | | log.warn("解析门诊采集时间失败:{}", value); |
| | | return null; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 前端/定时任务传入 yyyy-MM-dd 时,结束时间补齐到当天 23:59:59,避免漏掉当天数据。 |
| | | */ |
| | | private Date normalizeEndTime(Date endTime) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(endTime); |
| | | if (calendar.get(Calendar.HOUR_OF_DAY) == 0 && calendar.get(Calendar.MINUTE) == 0 |
| | | && calendar.get(Calendar.SECOND) == 0 && calendar.get(Calendar.MILLISECOND) == 0) { |
| | | calendar.add(Calendar.DAY_OF_MONTH, 1); |
| | | calendar.add(Calendar.SECOND, -1); |
| | | return calendar.getTime(); |
| | | } |
| | | return endTime; |
| | | } |
| | | |
| | | @Override |
| | | public Integer collectMchOuthospAndGenerateArchive(String orgid, Date startTime, Date endTime) { |
| | | if (!SpecificArchiveConstants.LISHUI_MCH_ORG_ID.equals(orgid)) { |
| | | log.warn("采集门诊接诊完成记录仅支持丽水市妇幼保健院,orgid={}", orgid); |
| | | return 0; |
| | | } |
| | | Date end = endTime != null ? normalizeEndTime(endTime) : new Date(); |
| | | Date start = startTime != null ? startTime : new Date(end.getTime() - 24 * 60 * 60 * 1000L); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | log.info("开始采集丽水妇幼门诊接诊完成记录,时间范围:{} ~ {}", sdf.format(start), sdf.format(end)); |
| | | int count = syncOuthosp(sdf.format(start), sdf.format(end), orgid, true); |
| | | log.info("丽水妇幼门诊接诊完成记录采集完成,时间范围:{} ~ {},处理数量:{}", |
| | | sdf.format(start), sdf.format(end), count); |
| | | return count; |
| | | } |
| | | |
| | | /** |
| | | * 同步手术信息 |
| | | * |
| | | * @param |
| | | * @return |
| | | */ |
| | | @Override |
| | | public Integer syncOper(String startTime, String endTime) { |
| | | Integer count = 0; |
| | | PatMedOperation patMedOperation = new PatMedOperation(); |
| | | patMedOperation.setLastStartTime(startTime); |
| | | patMedOperation.setLastEndTime(endTime); |
| | | List<PatMedOperation> patMedOperations = chMapper.selectOperList(patMedOperation); |
| | | Map<String, Long> patIdHisMap = buildOperationPatIdHisMap(patMedOperations); |
| | | |
| | | log.info("同步手术信息数量" + patMedOperations.size()); |
| | | for (PatMedOperation operation : patMedOperations) { |
| | | try { |
| | | if(ObjectUtils.isNotEmpty(operation.getCanceltime())){ |
| | | //作废删除操作 |
| | | cancelOper(operation); |
| | | continue; |
| | | } |
| | | Long patId = patIdHisMap.get(operation.getPatidHis()); |
| | | if (patId == null) { |
| | | patId = syncSinglePatient(operation.getPatidHis()); |
| | | if (patId != null) { |
| | | patIdHisMap.put(operation.getPatidHis(), patId); |
| | | } |
| | | } |
| | | |
| | | if (patId != null) { |
| | | operation.setPatid(patId); |
| | | } |
| | | PatMedOperation oper = new PatMedOperation(); |
| | | oper.setOpreqid(operation.getOpreqid()); |
| | | List<PatMedOperation> patMedOperations1 = otherVisitFacade.selectOperationList(oper); |
| | | if (CollectionUtils.isNotEmpty(patMedOperations1)) { |
| | | operation.setId(patMedOperations1.get(0).getId()); |
| | | operation.setUpdateTime(new Date()); |
| | | count += otherVisitFacade.updateOperation(operation); |
| | | syncOperItem(operation); |
| | | } else { |
| | | operation.setCreateTime(new Date()); |
| | | count += otherVisitFacade.insertOperation(operation); |
| | | syncOperItem(operation); |
| | | } |
| | | } catch (Exception ex) { |
| | | log.info("同步手术信息:" + ex.getMessage()); |
| | | } |
| | | } |
| | | return count; |
| | | } |
| | | |
| | | private Integer cancelOper(PatMedOperation oper){ |
| | | PatMedOperation operationVo = new PatMedOperation(); |
| | | operationVo.setOpreqid(oper.getOpreqid()); |
| | | List<PatMedOperation> operations = otherVisitFacade.selectOperationList(operationVo); |
| | | PatMedOperation operation = new PatMedOperation(); |
| | | if(CollectionUtils.isEmpty(operations)){ |
| | | return 0; |
| | | }else { |
| | | operation = operations.get(0); |
| | | } |
| | | log.info("手术作废id=" + operation.getId()); |
| | | PatMedOperationItem pmoi = new PatMedOperationItem(); |
| | | //获取需要出院手术随访,未处理的数据 |
| | | pmoi.setOpid(operation.getId().toString()); |
| | | List<PatMedOperationItem> patMedOperationItems |
| | | = otherVisitFacade.selectOperationItemListByCondition(pmoi); |
| | | List<Long> operationItemIds = patMedOperationItems.stream() |
| | | .map(PatMedOperationItem::getId) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | |
| | | //不需要服务了,需要通过patid和sendstate=1,2,3,5,7去查询一下,service_subtask里是否有正在执行的任务, |
| | | //有的话,立即停了 |
| | | List<Long> sendstates = Arrays.asList(1L, 2L, 3L, 5L, 7L); |
| | | List<ServiceSubtask> serviceSubtaskList = new ArrayList<>(); |
| | | ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity(); |
| | | serviceSubtaskVO.setOrgid(operation.getOrgid()); |
| | | serviceSubtaskVO.setPatid(operation.getPatid()); |
| | | serviceSubtaskVO.setSendstates(sendstates); |
| | | serviceSubtaskVO.setOperationItemIds(operationItemIds); |
| | | serviceSubtaskList = serviceSubtaskMapper.selectServiceSubtaskList(serviceSubtaskVO); |
| | | //去redis中,查询是否有subid,有的话移除cache-exist |
| | | if (CollectionUtils.isNotEmpty(serviceSubtaskList)) { |
| | | for (ServiceSubtask serviceSubtask : serviceSubtaskList) { |
| | | log.info("需要移除的subId为:{}", serviceSubtask.getId().toString()); |
| | | serviceSubtask.setSendstate(4L); |
| | | serviceSubtask.setRemark("手术撤销"); |
| | | serviceSubtaskMapper.updateServiceSubtask(serviceSubtask); |
| | | redisCache.removeElementFromList("cache-exist", serviceSubtask.getId().toString()); |
| | | redisCache.removeElementFromList("cache-0", serviceSubtask.getId().toString()); |
| | | redisCache.removeElementFromList("cache-1", serviceSubtask.getId().toString()); |
| | | redisCache.removeElementFromList("cache-2", serviceSubtask.getId().toString()); |
| | | redisCache.removeElementFromList("cache-3", serviceSubtask.getId().toString()); |
| | | redisCache.removeElementFromList("cache-4", serviceSubtask.getId().toString()); |
| | | } |
| | | } |
| | | operation.setUpdateTime(new Date()); |
| | | otherVisitFacade.updateOperation(operation); |
| | | otherVisitFacade.deleteSoftOperationItemByOpId(operation.getOpid()); |
| | | return 1; |
| | | } |
| | | |
| | | /** |
| | | * 同步手术信息 |
| | | * |
| | | * @param |
| | | * @return |
| | | */ |
| | | private Integer syncOperItem(PatMedOperation operation) { |
| | | if(ObjectUtils.isNotEmpty(operation.getId())){ |
| | | operation.setOpid(operation.getId().toString()); |
| | | } |
| | | operation.setUpdateTime(new Date()); |
| | | otherVisitFacade.updateOperation(operation); |
| | | |
| | | Integer count = 0; |
| | | if(StringUtils.isNotEmpty(operation.getOpid())){ |
| | | PatMedOperationItem patMedOperationItem = new PatMedOperationItem(); |
| | | //patMedOperation.opReqid = patMedOperationItem.operationid |
| | | List<PatMedOperationItem> patMedOperationItems = new ArrayList<>(); |
| | | if (ObjectUtils.isNotEmpty(operation.getOpreqid())){ |
| | | patMedOperationItem.setOperationid(operation.getOpreqid()); |
| | | patMedOperationItems = chMapper.selectOperItemList(patMedOperationItem); |
| | | }else { |
| | | log.info("同步手术详情信息:手术申请单ID为空!"); |
| | | return count; |
| | | } |
| | | |
| | | PatMedOperationItem operItem = new PatMedOperationItem(); |
| | | operItem.setOperationid(operation.getOpreqid()); |
| | | List<PatMedOperationItem> patMedOperationItems1 = otherVisitFacade.selectOperationItemList(operItem); |
| | | |
| | | Map<String, List<PatMedOperationItem>> maps = ArrayListUtils.splitListsById(patMedOperationItems, |
| | | patMedOperationItems1, PatMedOperationItem::getOperationid); |
| | | //只在视图的数据不在本地的数据,执行新增操作 |
| | | List<PatMedOperationItem> addItems = maps.get("onlyIn1"); |
| | | //只在本地的数据不在视图的数据,执行删除操作 |
| | | List<PatMedOperationItem> delItems = maps.get("onlyIn2"); |
| | | //重叠的数据,执行更新操作 patMedOperationItems的数据 |
| | | List<PatMedOperationItem> editItems = maps.get("common"); |
| | | |
| | | log.info("同步手术详情信息数量" + patMedOperationItems.size()); |
| | | |
| | | try{ |
| | | for (PatMedOperationItem operationItem : addItems) { |
| | | operationItem.setInhospstate(operation.getInhospstate()); |
| | | operationItem.setSerialnum(operation.getSerialnum()); |
| | | operationItem.setOpid(operation.getId().toString()); |
| | | operationItem.setOperationid(operation.getOpreqid()); |
| | | operationItem.setOpercheckFlag("0"); |
| | | operationItem.setCreateTime(new Date()); |
| | | count += otherVisitFacade.insertOperationItem(operationItem); |
| | | } |
| | | |
| | | for (PatMedOperationItem operationItem : delItems) { |
| | | operationItem.setUpdateTime(new Date()); |
| | | count += otherVisitFacade.deleteOperationItemByOperationid(operationItem.getOperationid()); |
| | | } |
| | | |
| | | for (PatMedOperationItem operationItem : editItems) { |
| | | operationItem.setInhospstate(operation.getInhospstate()); |
| | | operationItem.setSerialnum(operation.getSerialnum()); |
| | | operationItem.setOpid(operation.getId().toString()); |
| | | operationItem.setOperationid(operation.getOpreqid()); |
| | | operationItem.setUpdateTime(new Date()); |
| | | count += otherVisitFacade.updateOperationItemByOperationid(operationItem); |
| | | } |
| | | log.info("同步手术id={}详情信息数量, 新增{}条,删除{}条,修改{}条", operation.getId(), addItems.size(), delItems.size(), editItems.size()); |
| | | } catch (Exception ex) { |
| | | log.info("同步手术详情信息:" + ex.getMessage()); |
| | | } |
| | | |
| | | // try { |
| | | // otherVisitFacade.deleteHardOperationItemByOpId(operation.getOpid()); |
| | | // count += otherVisitFacade.insertOperationItems(patMedOperationItems); |
| | | // }catch (Exception ex) { |
| | | // log.info("同步手术详情信息:" + ex.getMessage()); |
| | | // } |
| | | } |
| | | return count; |
| | | } |
| | | |
| | | private Map<String, Long> buildOperationPatIdHisMap(List<PatMedOperation> operations) { |
| | | List<String> patidHiss = operations.stream() |
| | | .map(PatMedOperation::getPatidHis) |
| | | .filter(StringUtils::isNotEmpty) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | |
| | | if (CollectionUtils.isEmpty(patidHiss)) { |
| | | return new HashMap<>(); |
| | | } |
| | | |
| | | return patArchiveMapper.selectPatArchiveByPatidHiss(patidHiss).stream() |
| | | .filter(item -> StringUtils.isNotEmpty(item.getPatidHis()) && item.getId() != |
| | | null) |
| | | .collect(Collectors.toMap( |
| | | PatArchive::getPatidHis, |
| | | PatArchive::getId, |
| | | (a, b) -> a |
| | | )); |
| | | } |
| | | |
| | | private Long syncSinglePatient(String patidHis) { |
| | | if (StringUtils.isEmpty(patidHis)) { |
| | | return null; |
| | | } |
| | | |
| | | PatArchive hisQuery = new PatArchive(); |
| | | hisQuery.setPatidHis(patidHis); |
| | | hisQuery.setPageSize(5); |
| | | List<PatArchive> hisArchives = chMapper.selectPatArchiveList(hisQuery); |
| | | if (CollectionUtils.isEmpty(hisArchives)) { |
| | | return null; |
| | | } |
| | | |
| | | PatArchive localQuery = new PatArchive(); |
| | | localQuery.setPatidHis(patidHis); |
| | | List<PatArchive> localArchives = patArchiveMapper.selectPatArchiveList(localQuery); |
| | | |
| | | PatArchive hisArchive = hisArchives.get(0); |
| | | if (CollectionUtils.isNotEmpty(localArchives)) { |
| | | hisArchive.setId(localArchives.get(0).getId()); |
| | | hisArchive.setUpdateTime(new Date()); |
| | | patArchiveMapper.updatePatArchive(hisArchive); |
| | | return localArchives.get(0).getId(); |
| | | } else { |
| | | hisArchive.setCreateTime(new Date()); |
| | | patArchiveMapper.insertPatArchiveSingle(hisArchive); |
| | | return hisArchive.getId(); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | //入院 |
| | | pm.setInhospstate("0"); |
| | | pm.setCreateTime(new Date()); |
| | | patMedInhospMapper.insertPatMedInhosp(pm); |
| | | inhospVisitFacade.insertPatMedInhosp(pm); |
| | | } else if (!Objects.isNull(patMedInhosp.getStartOutHospTime()) && !Objects.isNull(patMedInhosp.getEndOutHospTime())) { |
| | | //出院 |
| | | pm.setInhospstate("1"); |
| | | pm.setUpdateTime(new Date()); |
| | | PatMedInhosp pmi = new PatMedInhosp(); |
| | | pmi.setSerialnum(pm.getSerialnum()); |
| | | List<PatMedInhosp> patMedInhospList1 = patMedInhospMapper.selectPatMedInhospList(pmi); |
| | | List<PatMedInhosp> patMedInhospList1 = inhospVisitFacade.selectPatMedInhospList(pmi); |
| | | if (CollectionUtils.isEmpty(patMedInhospList1)) { |
| | | pm.setCreateTime(new Date()); |
| | | patMedInhospMapper.insertPatMedInhosp(pm); |
| | | inhospVisitFacade.insertPatMedInhosp(pm); |
| | | } else { |
| | | pm.setInhospid(patMedInhospList1.get(0).getInhospid()); |
| | | patMedInhospMapper.updatePatMedInhosp(pm); |
| | | inhospVisitFacade.updatePatMedInhosp(pm); |
| | | } |
| | | |
| | | } |
| | |
| | | patArchiveMapper.insertPatArchiveSingle(patArchives.get(0)); |
| | | patMedOuthosp1.setPatid(patArchives.get(0).getId()); |
| | | } |
| | | i = patMedOuthospMapper.insertPatMedOuthosp(patMedOuthosp1); |
| | | i = patMedOuthospService.insertPatMedOuthosp(patMedOuthosp1); |
| | | } |
| | | |
| | | return i; |
| | |
| | | return size; |
| | | } |
| | | |
| | | /** |
| | | * 异步同步用户信息:接口立即返回,实际同步交给线程池后台执行。 |
| | | * 使用 AtomicBoolean 防止重复提交导致多个全量同步任务并发执行。 |
| | | */ |
| | | @Override |
| | | public boolean selectUserListAsync(SysUser sysUser) { |
| | | if (!userSyncRunning.compareAndSet(false, true)) { |
| | | log.warn("用户信息同步任务正在执行中,忽略本次提交"); |
| | | return false; |
| | | } |
| | | try { |
| | | taskExecutor.execute(() -> { |
| | | long start = System.currentTimeMillis(); |
| | | log.info("用户信息异步同步任务开始执行"); |
| | | try { |
| | | Integer count = selectUserList(sysUser); |
| | | log.info("用户信息异步同步任务执行完成,处理数量:{},耗时:{}ms", |
| | | count, System.currentTimeMillis() - start); |
| | | } catch (Throwable e) { |
| | | log.error("用户信息异步同步任务执行失败,耗时:{}ms", |
| | | System.currentTimeMillis() - start, e); |
| | | } finally { |
| | | userSyncRunning.set(false); |
| | | } |
| | | }); |
| | | return true; |
| | | } catch (RuntimeException e) { |
| | | userSyncRunning.set(false); |
| | | log.error("用户信息异步同步任务提交失败", e); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public Integer selectUserList(SysUser sysUser) { |
| | | List<SysUser> sysUserList = chMapper.selectUserList(sysUser); |
| | | SysUser suerTemp = new SysUser(); |
| | | //用户-机构关系-科室 |
| | | List<SysUserDept> sysUserDeptAll = chMapper.yhyksxx(suerTemp); |
| | | //用户-机构关系-病区 |
| | | List<SysUserDept> sysUserDeptBfAll = chMapper.yhybfxx(suerTemp); |
| | | //用户-院区关系 |
| | | List<SysUserOrg> sysUserOrgAll = chMapper.yhyyqxx(suerTemp); |
| | | |
| | | log.info("sysUserList的采集到的数量为:{}", sysUserList.size()); |
| | | int i = 0;// sysUser2Mapper.batchUser(sysUserList); |
| | | for (SysUser sysUser1 : sysUserList) { |
| | | // log.info("sysUser1的ID为:{}", sysUser1.getUserId()); |
| | | // log.info("sysUser1的HISUSERID为:{}", sysUser1.getHisUserId()); |
| | | if (StringUtils.isEmpty(sysUser1.getHisUserId())) continue; |
| | | SysUser suTemp = new SysUser(); |
| | | suTemp.setHisUserId(sysUser1.getHisUserId()); |
| | | List<SysUser> usersTemp = sysUser2Mapper.selectUserList(suTemp); |
| | | |
| | | //新增用户与科室 |
| | | List<SysUserDept> sysUserDept = sysUserDeptAll.stream().filter((SysUserDept b) -> |
| | | b.getUserCode().equals(sysUser1.getHisUserId())).collect(Collectors.toList()); |
| | | //新增用户与病区 |
| | | List<SysUserDept> sysUserDeptBf = sysUserDeptBfAll.stream().filter((SysUserDept b) -> |
| | | b.getUserCode().equals(sysUser1.getHisUserId())).collect(Collectors.toList()); |
| | | //新增用户与院区 |
| | | List<SysUserOrg> sysUserOrg = sysUserOrgAll.stream().filter((SysUserOrg o) -> |
| | | o.getUserId().equals(sysUser1.getHisUserId())).collect(Collectors.toList()); |
| | | |
| | | List<String> userDepts = sysUserDept.stream().map(SysUserDept::getDeptCode). |
| | | distinct().collect(Collectors.toList()); |
| | | |
| | | List<String> userDeptBfs = sysUserDeptBf.stream().map(SysUserDept::getDeptCode). |
| | | distinct().collect(Collectors.toList()); |
| | | |
| | | //和queryHospUserInfoList采集的数据格式保持一致 |
| | | List<List<String>> userDeptsList = new ArrayList<>(); |
| | | if(!userDepts.isEmpty()){ |
| | | for(String userDept: userDepts){ |
| | | List<String> uDept = new ArrayList<>(); |
| | | uDept.add(userDept); |
| | | userDeptsList.add(uDept); |
| | | } |
| | | } |
| | | List<List<String>> userDeptBfsList = new ArrayList<>(); |
| | | if(!userDeptBfs.isEmpty()){ |
| | | for(String userBfDept: userDeptBfs){ |
| | | List<String> uBfDept = new ArrayList<>(); |
| | | uBfDept.add(userBfDept); |
| | | userDeptBfsList.add(uBfDept); |
| | | } |
| | | } |
| | | |
| | | if (usersTemp.size() > 0) { |
| | | sysUser1.setUserId(usersTemp.get(0).getUserId()); |
| | | sysUser1.setUserName(sysUser1.getHisUserId()); |
| | | //对应 SysUserServiceImpl selectUserByUserName2 191行 |
| | | if (!org.springframework.util.CollectionUtils.isEmpty(sysUserOrg)) { |
| | | sysUser1.setOrgid(sysUserOrg.get(0).getOrgid()); |
| | | sysUser1.setCampusid(sysUserOrg.get(0).getCampusid()); |
| | | } |
| | | //将部门我病区放到指定字段中 |
| | | Gson gson = new Gson(); |
| | | sysUser1.setHospInfo(gson.toJson(userDeptsList)); |
| | | sysUser1.setDeptInfo(gson.toJson(userDeptBfsList)); |
| | | |
| | | sysUser2Mapper.updateUser(sysUser1); |
| | | } else { |
| | | sysUser1.setUserName(sysUser1.getHisUserId()); |
| | | //将部门我病区放到指定字段中 |
| | | Gson gson = new Gson(); |
| | | sysUser1.setHospInfo(gson.toJson(userDeptsList)); |
| | | sysUser1.setDeptInfo(gson.toJson(userDeptBfsList)); |
| | | |
| | | sysUser2Mapper.insertUser(sysUser1); |
| | | //对应 SysUserServiceImpl selectUserByUserName2 191行 |
| | | if (!org.springframework.util.CollectionUtils.isEmpty(sysUserOrg)) { |
| | | sysUser1.setOrgid(sysUserOrg.get(0).getOrgid()); |
| | | sysUser1.setCampusid(sysUserOrg.get(0).getCampusid()); |
| | | } |
| | | usersTemp = sysUser2Mapper.selectUserList(suTemp); |
| | | } |
| | | |
| | | //新增用户与部门 |
| | | //List<SysUserDept> sysUserDept = chMapper.yhyksxx(sysUser1); |
| | | List<SysUserDept> sysUserDept = sysUserDeptAll.stream().filter((SysUserDept b) -> b.getUserCode().equals(sysUser1.getHisUserId())).collect(Collectors.toList()); |
| | | |
| | | for (SysUserDept sud : sysUserDept) { |
| | | if (usersTemp.size() > 0) { |
| | | if (!usersTemp.isEmpty()) { |
| | | sud.setDeptType("1"); |
| | | sud.setUserId(usersTemp.get(0).getUserId()); |
| | | sysUserDeptMapper.insertSysUserDept(sud); |
| | | } |
| | | } |
| | | //新增用户与院区 |
| | | List<SysUserOrg> sysUserOrg = sysUserOrgAll.stream().filter((SysUserOrg o) -> o.getUserId().equals(sysUser1.getHisUserId())).collect(Collectors.toList()); |
| | | for (SysUserDept sudb : sysUserDeptBf) { |
| | | if (!usersTemp.isEmpty()) { |
| | | sudb.setDeptType("2"); |
| | | sudb.setUserId(usersTemp.get(0).getUserId()); |
| | | sysUserDeptMapper.insertSysUserDept(sudb); |
| | | } |
| | | } |
| | | for (SysUserOrg suo : sysUserOrg) { |
| | | if (usersTemp.size() > 0) { |
| | | suo.setUserId(usersTemp.get(0).getUserId()); |
| | | if (!usersTemp.isEmpty()) { |
| | | suo.setUserId(usersTemp.get(0).getUserId().toString()); |
| | | sysUserOrgMapper.insertSysUserOrg(suo); |
| | | } |
| | | } |
| | |
| | | log.info("selectDeptList的采集到的数量为:{}", sysDepts.size()); |
| | | // count = sysDept2Mapper.batchDept(sysDepts); |
| | | for (SysDept row : sysDepts) { |
| | | SysDept sysDeptTemp = sysDept2Mapper.selectDeptByCode(row.getDeptCode(), null); |
| | | // 科室和病区可能共用同一个 dept_code,必须按 dept_type + orgid 精确定位,否则 selectOne 会返回多条 |
| | | if (StringUtils.isEmpty(row.getDeptCode())) { |
| | | log.warn("selectDeptList跳过deptCode为空的记录:{}", row); |
| | | continue; |
| | | } |
| | | SysDept sysDeptTemp = sysDept2Mapper.selectDeptByCodeAndType(row.getDeptCode(), row.getOrgid(), row.getDeptType()); |
| | | if (sysDeptTemp != null && sysDeptTemp.getDeptName() != null) { |
| | | row.setDeptId(sysDeptTemp.getDeptId()); |
| | | count += sysDept2Mapper.updateDept(row); |