陈昶聿
4 天以前 eb845e8be695ed1280a7cbf854a4d1dedf9db30d
smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java
@@ -22,6 +22,7 @@
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;
@@ -2009,10 +2010,11 @@
    /**
     * 人工随访:删除患者出院记录对应的未完成随访任务,并按指定任务重新生成。
     * 未完成状态口径: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("入参不能为空");
@@ -2029,20 +2031,27 @@
            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 按出院时间倒序,第一条作为本次生成任务的出院记录
@@ -2067,6 +2076,26 @@
            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;
            }
@@ -2111,14 +2140,29 @@
                    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;
    }