From eb845e8be695ed1280a7cbf854a4d1dedf9db30d Mon Sep 17 00:00:00 2001
From: 陈昶聿 <chychen@nbjetron.com>
Date: 星期五, 30 十月 2026 15:02:55 +0800
Subject: [PATCH] 【丽水】/smartor/serviceSubtask/getSfStatisticsHyperlink 和 /smartor/serviceSubtask/getSfStatistics 统计的时候,对于 service_subtask.current_preachForm 为空的数据 当成 service_subtask.preachform 字符串的第一个执行方式、首次待随访全部(visitCount = 1 && sendstate in (1、2、3、7)) 区别于原先的待随访,这个是给市一使用的                                                                                                                                                                                            再次待随访全部(visitCount > 1 && sendstate in (1、2、3、7)) 区别于原先的待随访,这个是给市一使用的                                                                                                                                                                                            首次待随访待发送(visitCount = 1 && sendstate in (1、2))                                                                                                                                                                                            再次待随访待发送(visitCount > 1 && sendstate in (1、2))                                                                                                                                                                                            首次待随访已发送(visitCount = 1 && sendstate = in (3、7))                                                                                                                                                                                            再次待随访已发送(visitCount > 1 && sendstate = in (3、7))                                                                                                                                                                                            首次已发送(visitCount = 1 && sendstate = 3)                                                                                                                                                                                            再次已发送(visitCount > 1 && sendstate = 3)

---
 smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java
index c6db543..8cf5d67 100644
--- a/smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java
+++ b/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)锛�
+     * 閲嶅浠诲姟鏍¢獙鍙e緞锛歴endstate in (1,2,3,5,7)锛屽凡鏈夌浉鍚� taskid 鏈畬鎴愪换鍔$殑鎮h�呰烦杩囥��
      */
     @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("鎮h�卲atid闆嗗悎涓嶈兘涓虹┖");
         }
 
         String config = iSysConfigService.selectConfigByKey("visit.early.day");
         List<Long> unfinishedSendstates = Arrays.asList(1L, 2L, 3L, 7L);
+        // 涓庡墠绔緟闅忚鍙e緞淇濇寔涓�鑷达紝鍙戦�佸け璐�(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) {
             // 鏌ヨ鎮h�呭叏閮ㄥ嚭闄㈣褰曪紝SQL 鎸夊嚭闄㈡椂闂村�掑簭锛岀涓�鏉′綔涓烘湰娆$敓鎴愪换鍔$殑鍑洪櫌璁板綍
@@ -2067,6 +2076,26 @@
             PatArchive patArchive = patArchiveMapper.selectPatArchiveByPatid(patid);
             if (Objects.isNull(patArchive)) {
                 noArchivePatids.add(patid);
+                continue;
+            }
+
+            // 閿佸畾鎮h�呮。妗堣锛屼覆琛屽寲鍚屼竴鎮h�呯殑骞跺彂鍒涘缓璇锋眰
+            Long lockedPatid = patArchiveMapper.lockPatArchiveByPatid(patid);
+            if (Objects.isNull(lockedPatid)) {
+                noArchivePatids.add(patid);
+                continue;
+            }
+
+            // 鍚屼竴鎮h�呭湪鍚屼竴 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 鎮h�呭凡鏈夌浉鍚屾湇鍔★紝璺宠繃鐢熸垚锛宲atid锛歿}锛宼askid锛歿}锛屽凡鏈変换鍔℃暟锛歿}",
+                        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 = "鎮h��" + 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 澶勭悊瀹屾垚锛宲atid鏁帮細{}锛宼askid锛歿}锛屽垹闄ゆ湭瀹屾垚浠诲姟鏁帮細{}锛岀敓鎴愪换鍔℃暟锛歿}",
-                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 澶勭悊瀹屾垚锛宲atid鏁帮細{}锛宼askid锛歿}锛屽垹闄ゆ湭瀹屾垚浠诲姟鏁帮細{}锛岀敓鎴愪换鍔℃暟锛歿}锛岄噸澶嶈烦杩囨暟锛歿}",
+                patids.size(), serviceTask.getTaskid(), deletedCount, generatedCount, duplicatePatids.size());
         return result;
     }
 

--
Gitblit v1.9.3