| | |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.ruoyi.common.core.domain.entity.SysDept; |
| | | import com.ruoyi.common.core.service.IConfigService; |
| | | import com.ruoyi.common.exception.base.BaseException; |
| | | import com.ruoyi.common.utils.DateUtils; |
| | | import com.ruoyi.common.utils.DtoConversionUtils; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.smartor.common.ScheduleSubtaskBuilder; |
| | | import com.smartor.domain.*; |
| | | import com.smartor.domain.DTO.ManualVisitDTO; |
| | | import com.smartor.domain.DTO.PatMedInhospDTO; |
| | | import com.smartor.domain.entity.ServiceSubtaskEntity; |
| | | import com.smartor.mapper.*; |
| | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.ObjectUtils; |
| | | |
| | | import java.io.IOException; |
| | |
| | | */ |
| | | @Override |
| | | public List<PatMedInhosp> selectPatMedInhospList(PatMedInhosp patMedInhosp) { |
| | | //入院床位排序只在「在院」查询(cry=0)下生效,其它查询一律忽略,保证原有排序不变 |
| | | patMedInhosp.setBedSort(normalizeBedSort(patMedInhosp.getCry(), patMedInhosp.getBedSort())); |
| | | if (patMedInhosp.getCry() != null && patMedInhosp.getCry() == 0) { |
| | | patMedInhosp.setDeptcodeList(patMedInhosp.getLeaveldeptcodes()); |
| | | patMedInhosp.setHospitaldistrictcodeList(patMedInhosp.getLeavehospitaldistrictcodes()); |
| | |
| | | patMedInhosp1.setTagname(tagname); |
| | | } |
| | | return patMedInhospList; |
| | | } |
| | | |
| | | /** |
| | | * 归一化入院床位排序参数 |
| | | * <p> |
| | | * asc / 1 -> asc(床位正序),desc / 2 -> desc(床位倒序),其余(含不传)-> null(不排序)。 |
| | | * 只对「在院」患者查询(cry=0)生效,出院/转科等查询忽略该参数。 |
| | | * |
| | | * @param cry 出入院标识:0入院 1出院 2转科 3预入院 |
| | | * @param bedSort 前端传入的床位排序值 |
| | | * @return 归一化后的排序值(asc / desc / null) |
| | | */ |
| | | private String normalizeBedSort(Integer cry, String bedSort) { |
| | | if (cry == null || cry != 0 || StringUtils.isEmpty(bedSort)) return null; |
| | | String value = bedSort.trim().toLowerCase(); |
| | | if ("asc".equals(value) || "1".equals(value)) return "asc"; |
| | | if ("desc".equals(value) || "2".equals(value)) return "desc"; |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | |
| | | pmoi.setDeptCodes(deptCodeList); |
| | | pmoi.setWardCodes(wardCodeList); |
| | | pmoi.setOpLevelCodes(opLevelCodeList); |
| | | List<PatMedOperationItem> patMedOperationItems = patMedOperationItemMapper.selectOperationItemList(pmoi); |
| | | |
| | | //每次查询只查最大的手术等级记录 |
| | | List<PatMedOperationItem> patMedOperationItems = patMedOperationItemMapper.selectOperationItemListMaxLevel(pmoi); |
| | | for (PatMedOperationItem patMedOperationItem : patMedOperationItems) { |
| | | PatArchive patArchive = patArchiveMapper.selectPatArchiveByPatid(patMedOperationItem.getPatid()); |
| | | if (Objects.isNull(patArchive)) { |
| | |
| | | //记录insertServiceSubtask语句返回状态 |
| | | Integer i = 0; |
| | | try { |
| | | // 兜底:任务模板修改会重置 pat_med_inhosp 的处理标记,但已完成的首访不会删除。 |
| | | // 同一 inhospid + taskid 已存在未删除的首次随访(upid 为空)时,不再插入,避免出现两条首次随访。 |
| | | if (check |
| | | && ("2".equals(serviceTask.getServiceType()) || "13".equals(serviceTask.getServiceType())) |
| | | && (type == 1 || type == 2 || type == 3)) { |
| | | ServiceSubtaskEntity firstQuery = new ServiceSubtaskEntity(); |
| | | firstQuery.setInhospid(patMedInhosp1.getInhospid()); |
| | | firstQuery.setTaskid(taskid); |
| | | List<ServiceSubtask> firstList = serviceSubtaskMapper.selectServiceSubtaskList(firstQuery); |
| | | boolean firstExists = CollectionUtils.isNotEmpty(firstList) |
| | | && firstList.stream().anyMatch(item -> item.getUpid() == null); |
| | | if (firstExists) { |
| | | log.info("患者{}已存在首次随访任务,跳过重复生成, taskid={}, type={}", |
| | | patMedInhosp1.getInhospid(), taskid, type); |
| | | PatMedInhosp flagUpdate = new PatMedInhosp(); |
| | | flagUpdate.setInhospid(patMedInhosp1.getInhospid()); |
| | | if (type == 1) flagUpdate.setDeptcheckFlag("1"); |
| | | if (type == 2) flagUpdate.setWardcheckFlag("1"); |
| | | if (type == 3) flagUpdate.setDiagcheckFlag("1"); |
| | | patMedInhospMapper.updatePatMedInhosp(flagUpdate); |
| | | return; |
| | | } |
| | | } |
| | | //先判断一下,是否需要校验 |
| | | if (check && (Objects.isNull(serviceSubtask.getTaskSituation()) || serviceSubtask.getTaskSituation() != 6)) { |
| | | //在新增之前,先通过患者ID,sendstate=2查询一下,在所有长期任务中,是不是还有该患者待执行的任务,有的话,比较之前的endtime是否小于当前的endtaime,如果之前的小于现在的,则直接将之前的停掉(原因再入院) |
| | |
| | | } |
| | | } |
| | | |
| | | private Integer addServiceSubtaskPreachform(ServiceSubtask serviceSubtask, String sendstate) { |
| | | @Override |
| | | public Integer addServiceSubtaskPreachform(ServiceSubtask serviceSubtask, String sendstate) { |
| | | //将preachformDesc的json对象,放到list集合中 |
| | | ServiceTask serviceTask = serviceTaskMapper.selectServiceTaskByTaskid(serviceSubtask.getTaskid()); |
| | | if (Objects.isNull(serviceTask)) { |
| | |
| | | pmoi.setOpercheckFlag("0"); |
| | | pmoi.setMainFlag("1"); |
| | | |
| | | List<PatMedOperationItem> patMedOperationItems = patMedOperationItemMapper.selectOperationItemList(pmoi); |
| | | //每次查询只查最大的手术等级记录 |
| | | List<PatMedOperationItem> patMedOperationItems = patMedOperationItemMapper.selectOperationItemListMaxLevel(pmoi); |
| | | log.info("dealOutHospInfo需要处理的出院手术患者信息:{}", CollectionUtils.isNotEmpty(patMedOperationItems) ? patMedOperationItems.size() : null); |
| | | |
| | | for (PatMedOperationItem opItem : patMedOperationItems) { |
| | |
| | | return generatedCount; |
| | | } |
| | | |
| | | @Override |
| | | public void dealIcd10Subtask(PatMedInhosp pmks, String config) { |
| | | pmks.setDiagcheckFlag("0"); |
| | | pmks.setInhospstate("1"); |
| | | pmks.setFuflag("1"); |
| | | List<PatMedInhosp> patMedInhosps = patMedInhospMapper.selectPatMedInhospList(pmks); |
| | | log.info("dealIcd10Subtask 待处理出院疾病患者数:{}", CollectionUtils.isEmpty(patMedInhosps) ? 0 : patMedInhosps.size()); |
| | | if (CollectionUtils.isNotEmpty(patMedInhosps)) { |
| | | int matchedTaskCount = 0; |
| | | for (PatMedInhosp patMedInhosp : patMedInhosps) { |
| | | // 获取患者基本信息,档案不存在时直接标记失败,避免后续空指针 |
| | | PatArchive patArchive = patArchiveMapper.selectPatArchiveByPatid(patMedInhosp.getPatid()); |
| | | if (Objects.isNull(patArchive)) { |
| | | PatMedInhosp updateObj = new PatMedInhosp(); |
| | | updateObj.setInhospid(patMedInhosp.getInhospid()); |
| | | updateObj.setDiagcheckFlag("2"); |
| | | updateObj.setLongTaskReason("患者基本信息为空"); |
| | | patMedInhospMapper.updatePatMedInhosp(updateObj); |
| | | continue; |
| | | } |
| | | matchedTaskCount += addIcd10SubTaskForPatient(patMedInhosp, patArchive, config); |
| | | } |
| | | log.info("dealIcd10Subtask 处理完成,待处理:{},匹配疾病长期任务次数:{}", patMedInhosps.size(), matchedTaskCount); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 人工随访:删除患者出院记录对应的未完成随访任务,并按指定任务重新生成。 |
| | | * 未完成状态口径:sendstate in (1,2,3,7)。 |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Map<String, Object> addManualVisit(ManualVisitDTO manualVisitDTO) { |
| | | if (manualVisitDTO == null) { |
| | | throw new BaseException("入参不能为空"); |
| | | } |
| | | if (CollectionUtils.isEmpty(manualVisitDTO.getPatids())) { |
| | | throw new BaseException("患者patid集合不能为空"); |
| | | } |
| | | if (manualVisitDTO.getTaskid() == null) { |
| | | throw new BaseException("人工随访任务taskid不能为空"); |
| | | } |
| | | |
| | | ServiceTask serviceTask = serviceTaskMapper.selectServiceTaskByTaskid(manualVisitDTO.getTaskid()); |
| | | if (Objects.isNull(serviceTask)) { |
| | | throw new BaseException("人工随访任务不存在,taskid:" + manualVisitDTO.getTaskid()); |
| | | } |
| | | |
| | | LinkedHashSet<Long> patids = manualVisitDTO.getPatids().stream() |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toCollection(LinkedHashSet::new)); |
| | | if (patids.isEmpty()) { |
| | | throw new BaseException("患者patid集合不能为空"); |
| | | } |
| | | |
| | | String config = iSysConfigService.selectConfigByKey("visit.early.day"); |
| | | List<Long> unfinishedSendstates = Arrays.asList(1L, 2L, 3L, 7L); |
| | | int deletedCount = 0; |
| | | int generatedCount = 0; |
| | | List<Long> noDischargeRecordPatids = new ArrayList<>(); |
| | | List<Long> noArchivePatids = new ArrayList<>(); |
| | | List<Long> generateFailedPatids = new ArrayList<>(); |
| | | |
| | | for (Long patid : patids) { |
| | | // 查询患者全部出院记录,SQL 按出院时间倒序,第一条作为本次生成任务的出院记录 |
| | | PatMedInhosp query = new PatMedInhosp(); |
| | | query.setPatid(patid); |
| | | query.setCry(1); |
| | | if (StringUtils.isNotEmpty(serviceTask.getOrgid())) { |
| | | query.setOrgid(serviceTask.getOrgid()); |
| | | } |
| | | List<PatMedInhosp> inhospList = patMedInhospMapper.selectPatMedInhospList(query); |
| | | if (CollectionUtils.isEmpty(inhospList)) { |
| | | noDischargeRecordPatids.add(patid); |
| | | continue; |
| | | } |
| | | |
| | | PatMedInhosp latestInhosp = inhospList.get(0); |
| | | if (Objects.isNull(latestInhosp.getEndtime())) { |
| | | noDischargeRecordPatids.add(patid); |
| | | continue; |
| | | } |
| | | |
| | | PatArchive patArchive = patArchiveMapper.selectPatArchiveByPatid(patid); |
| | | if (Objects.isNull(patArchive)) { |
| | | noArchivePatids.add(patid); |
| | | continue; |
| | | } |
| | | |
| | | // 先构建新任务,构建失败时不删除原任务,避免患者丢失待随访任务 |
| | | ServiceSubtask serviceSubtask = boxedServiceSubtask(serviceTask, latestInhosp, patArchive, config, 1); |
| | | if (Objects.isNull(serviceSubtask) || Objects.isNull(serviceSubtask.getTaskid())) { |
| | | generateFailedPatids.add(patid); |
| | | continue; |
| | | } |
| | | |
| | | List<Long> inhospids = inhospList.stream() |
| | | .map(PatMedInhosp::getInhospid) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | if (CollectionUtils.isNotEmpty(inhospids)) { |
| | | deletedCount += serviceSubtaskMapper.deleteUnfinishedServiceSubtaskByInhospids( |
| | | patid, inhospids, unfinishedSendstates); |
| | | } |
| | | |
| | | serviceSubtask.setId(null); |
| | | serviceSubtask.setUpid(null); |
| | | serviceSubtask.setVisitDeptCode(StringUtils.isNotEmpty(latestInhosp.getLeaveldeptcode()) |
| | | ? latestInhosp.getLeaveldeptcode() : latestInhosp.getLeavehospitaldistrictcode()); |
| | | serviceSubtask.setVisitDeptName(StringUtils.isNotEmpty(latestInhosp.getLeaveldeptname()) |
| | | ? latestInhosp.getLeaveldeptname() : latestInhosp.getLeavehospitaldistrictname()); |
| | | // 与常规生成逻辑保持一致:手机号为空时生成任务但不执行 |
| | | if (StringUtils.isEmpty(serviceSubtask.getPhone())) { |
| | | serviceSubtask.setRemark(StringUtils.isNotEmpty(serviceSubtask.getRemark()) |
| | | ? serviceSubtask.getRemark() + ",手机号为空" : "手机号为空"); |
| | | serviceSubtask.setSendstate(4L); |
| | | serviceSubtask.setResult("error"); |
| | | } |
| | | |
| | | int inserted = serviceSubtaskMapper.insertServiceSubtask(serviceSubtask); |
| | | if (inserted != 1) { |
| | | throw new BaseException("生成随访任务失败,patid:" + patid + ",taskid:" + serviceTask.getTaskid()); |
| | | } |
| | | addServiceSubtaskPreachform(serviceSubtask, null); |
| | | generatedCount++; |
| | | log.info("addManualVisit 生成随访任务成功,patid:{},taskid:{},subtaskId:{}", |
| | | patid, serviceTask.getTaskid(), serviceSubtask.getId()); |
| | | } |
| | | |
| | | Map<String, Object> result = new HashMap<>(); |
| | | result.put("deletedCount", deletedCount); |
| | | result.put("generatedCount", generatedCount); |
| | | result.put("noDischargeRecordPatids", noDischargeRecordPatids); |
| | | result.put("noArchivePatids", noArchivePatids); |
| | | result.put("generateFailedPatids", generateFailedPatids); |
| | | log.info("addManualVisit 处理完成,patid数:{},taskid:{},删除未完成任务数:{},生成任务数:{}", |
| | | patids.size(), serviceTask.getTaskid(), deletedCount, generatedCount); |
| | | return result; |
| | | } |
| | | |
| | | } |