| | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Isolation; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.ObjectUtils; |
| | | |
| | |
| | | |
| | | /** |
| | | * 人工随访:删除患者出院记录对应的未完成随访任务,并按指定任务重新生成。 |
| | | * 未完成状态口径:sendstate in (1,2,3,7)。 |
| | | * 删除旧任务口径:sendstate in (1,2,3,7); |
| | | * 重复任务校验口径:sendstate in (1,2,3,5,7),已有相同 taskid 未完成任务的患者跳过。 |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED) |
| | | public Map<String, Object> addManualVisit(ManualVisitDTO manualVisitDTO) { |
| | | if (manualVisitDTO == null) { |
| | | throw new BaseException("入参不能为空"); |
| | |
| | | throw new BaseException("人工随访任务不存在,taskid:" + manualVisitDTO.getTaskid()); |
| | | } |
| | | |
| | | LinkedHashSet<Long> patids = manualVisitDTO.getPatids().stream() |
| | | // 升序处理,配合患者档案行锁,避免批量请求交叉加锁产生死锁 |
| | | List<Long> patids = manualVisitDTO.getPatids().stream() |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toCollection(LinkedHashSet::new)); |
| | | .distinct() |
| | | .sorted() |
| | | .collect(Collectors.toList()); |
| | | if (patids.isEmpty()) { |
| | | throw new BaseException("患者patid集合不能为空"); |
| | | } |
| | | |
| | | String config = iSysConfigService.selectConfigByKey("visit.early.day"); |
| | | List<Long> unfinishedSendstates = Arrays.asList(1L, 2L, 3L, 7L); |
| | | // 与前端待随访口径保持一致,发送失败(5)也视为已有未完成任务 |
| | | List<Long> activeSendstates = Arrays.asList(1L, 2L, 3L, 5L, 7L); |
| | | int deletedCount = 0; |
| | | int generatedCount = 0; |
| | | List<Long> noDischargeRecordPatids = new ArrayList<>(); |
| | | List<Long> noArchivePatids = new ArrayList<>(); |
| | | List<Long> generateFailedPatids = new ArrayList<>(); |
| | | List<Long> duplicatePatids = new ArrayList<>(); |
| | | List<String> duplicatePatientNames = new ArrayList<>(); |
| | | |
| | | for (Long patid : patids) { |
| | | // 查询患者全部出院记录,SQL 按出院时间倒序,第一条作为本次生成任务的出院记录 |
| | |
| | | PatArchive patArchive = patArchiveMapper.selectPatArchiveByPatid(patid); |
| | | if (Objects.isNull(patArchive)) { |
| | | noArchivePatids.add(patid); |
| | | continue; |
| | | } |
| | | |
| | | // 锁定患者档案行,串行化同一患者的并发创建请求 |
| | | Long lockedPatid = patArchiveMapper.lockPatArchiveByPatid(patid); |
| | | if (Objects.isNull(lockedPatid)) { |
| | | noArchivePatids.add(patid); |
| | | continue; |
| | | } |
| | | |
| | | // 同一患者在同一 taskid 下已有未完成随访任务时,跳过该患者,避免重复创建 |
| | | int existingSubtaskCount = serviceSubtaskMapper.countUnfinishedServiceSubtaskByPatidAndTaskid( |
| | | patid, serviceTask.getTaskid(), activeSendstates); |
| | | if (existingSubtaskCount > 0) { |
| | | duplicatePatids.add(patid); |
| | | String patientName = StringUtils.isNotEmpty(patArchive.getName()) |
| | | ? patArchive.getName() : String.valueOf(patid); |
| | | duplicatePatientNames.add(patientName + "(" + patid + ")"); |
| | | log.info("addManualVisit 患者已有相同服务,跳过生成,patid:{},taskid:{},已有任务数:{}", |
| | | patid, serviceTask.getTaskid(), existingSubtaskCount); |
| | | continue; |
| | | } |
| | | |
| | |
| | | patid, serviceTask.getTaskid(), serviceSubtask.getId()); |
| | | } |
| | | |
| | | String tipMessage = null; |
| | | if (CollectionUtils.isNotEmpty(duplicatePatids)) { |
| | | String taskName = StringUtils.isNotEmpty(serviceTask.getTaskName()) |
| | | ? serviceTask.getTaskName() : String.valueOf(serviceTask.getTaskid()); |
| | | tipMessage = "患者" + String.join("、", duplicatePatientNames) |
| | | + "已有相同服务【" + taskName + "】,已跳过"; |
| | | if (generatedCount > 0) { |
| | | tipMessage += ";其余患者已处理"; |
| | | } |
| | | } |
| | | |
| | | 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); |
| | | result.put("duplicatePatids", duplicatePatids); |
| | | result.put("duplicatePatientNames", duplicatePatientNames); |
| | | result.put("hasDuplicate", CollectionUtils.isNotEmpty(duplicatePatids)); |
| | | result.put("tipMessage", tipMessage); |
| | | log.info("addManualVisit 处理完成,patid数:{},taskid:{},删除未完成任务数:{},生成任务数:{},重复跳过数:{}", |
| | | patids.size(), serviceTask.getTaskid(), deletedCount, generatedCount, duplicatePatids.size()); |
| | | return result; |
| | | } |
| | | |