From 43e807c405e8cf5b725d1ced5490128da191eb98 Mon Sep 17 00:00:00 2001
From: 陈昶聿 <chychen@nbjetron.com>
Date: 星期五, 30 十月 2026 11:34:38 +0800
Subject: [PATCH] 【丽水】/smartor/patinhosp/addManualVisit 人工处理,接口完成删除未完成的任务,再次生成随访任务

---
 smartor/src/main/java/com/smartor/service/IPatMedInhospService.java                    |    9 +++
 smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java            |  118 +++++++++++++++++++++++++++++++++++++++
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java |   10 +++
 smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java                     |   12 ++++
 smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml                     |   16 +++++
 5 files changed, 165 insertions(+), 0 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java
index 9ce9406..8b28e85 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java
@@ -12,6 +12,7 @@
 import com.ruoyi.common.utils.PageUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.system.service.ISysConfigService;
+import com.smartor.domain.DTO.ManualVisitDTO;
 import com.smartor.domain.DTO.PatMedInhospDTO;
 import com.smartor.domain.PatMedInhosp;
 import com.smartor.domain.PatMedInhospVO;
@@ -268,6 +269,15 @@
     }
 
     /**
+     * 鎮h�呬汉宸ラ殢璁匡細鍒犻櫎鏈畬鎴愰殢璁夸换鍔″苟鎸夋寚瀹氫换鍔¢噸鏂扮敓鎴�
+     */
+    @ApiOperation("addManualVisit")
+    @PostMapping("/addManualVisit")
+    public AjaxResult addManualVisit(@RequestBody ManualVisitDTO manualVisitDTO) {
+        return success(patMedInhospService.addManualVisit(manualVisitDTO));
+    }
+
+    /**
      * 澶勭悊鎮h�呬俊鎭紝杩涘叆瀛愪换鍔¤〃
      */
     @ApiOperation("dealOutHospInfoBySchedule")
diff --git a/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java b/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java
index a27f4b7..4c633bf 100644
--- a/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java
+++ b/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java
@@ -156,6 +156,18 @@
     public int deleteServiceSubtaskByCondition(@Param("taskid") Long id, @Param("patid") Long patid);
 
     /**
+     * 鍒犻櫎鎮h�呭嚭闄㈣褰曞搴旂殑鏈畬鎴愰殢璁夸换鍔�
+     *
+     * @param patid      鎮h�匢D
+     * @param inhospids  鍑洪櫌璁板綍ID闆嗗悎
+     * @param sendstates 鏈畬鎴愮姸鎬侀泦鍚�
+     * @return 鍒犻櫎鏉℃暟
+     */
+    public int deleteUnfinishedServiceSubtaskByInhospids(@Param("patid") Long patid,
+                                                         @Param("inhospids") List<Long> inhospids,
+                                                         @Param("sendstates") List<Long> sendstates);
+
+    /**
      * 鍒犻櫎鍗曚竴浠诲姟锛堥殢璁匡級
      *
      * @return 缁撴灉
diff --git a/smartor/src/main/java/com/smartor/service/IPatMedInhospService.java b/smartor/src/main/java/com/smartor/service/IPatMedInhospService.java
index 75ef105..17b2c6f 100644
--- a/smartor/src/main/java/com/smartor/service/IPatMedInhospService.java
+++ b/smartor/src/main/java/com/smartor/service/IPatMedInhospService.java
@@ -3,6 +3,7 @@
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.smartor.domain.*;
+import com.smartor.domain.DTO.ManualVisitDTO;
 import com.smartor.domain.DTO.PatMedInhospDTO;
 import org.springframework.web.bind.annotation.RequestBody;
 
@@ -135,6 +136,14 @@
      */
     public void dealIcd10Subtask(PatMedInhosp patMedInhospVo, String config);
 
+    /**
+     * 浜哄伐闅忚锛氬垹闄ゆ偅鑰呭嚭闄㈣褰曞搴旂殑鏈畬鎴愰殢璁夸换鍔★紝骞舵寜鎸囧畾浠诲姟閲嶆柊鐢熸垚
+     *
+     * @param manualVisitDTO 鎮h�卲atid闆嗗悎鍙婁汉宸ラ殢璁夸换鍔askid
+     * @return 澶勭悊缁撴灉
+     */
+    public Map<String, Object> addManualVisit(ManualVisitDTO manualVisitDTO);
+
     public ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, PatMedInhosp patMedInhosp1, PatArchive patArchive, String config, Integer type);
 
     /**
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 e1ba487..c6db543 100644
--- a/smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java
@@ -5,12 +5,14 @@
 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.*;
@@ -20,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.Transactional;
 import org.springframework.util.ObjectUtils;
 
 import java.io.IOException;
@@ -2004,4 +2007,119 @@
         }
     }
 
+    /**
+     * 浜哄伐闅忚锛氬垹闄ゆ偅鑰呭嚭闄㈣褰曞搴旂殑鏈畬鎴愰殢璁夸换鍔★紝骞舵寜鎸囧畾浠诲姟閲嶆柊鐢熸垚銆�
+     * 鏈畬鎴愮姸鎬佸彛寰勶細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("鎮h�卲atid闆嗗悎涓嶈兘涓虹┖");
+        }
+        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("鎮h�卲atid闆嗗悎涓嶈兘涓虹┖");
+        }
+
+        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) {
+            // 鏌ヨ鎮h�呭叏閮ㄥ嚭闄㈣褰曪紝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("鐢熸垚闅忚浠诲姟澶辫触锛宲atid锛�" + patid + "锛宼askid锛�" + serviceTask.getTaskid());
+            }
+            addServiceSubtaskPreachform(serviceSubtask, null);
+            generatedCount++;
+            log.info("addManualVisit 鐢熸垚闅忚浠诲姟鎴愬姛锛宲atid锛歿}锛宼askid锛歿}锛宻ubtaskId锛歿}",
+                    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 澶勭悊瀹屾垚锛宲atid鏁帮細{}锛宼askid锛歿}锛屽垹闄ゆ湭瀹屾垚浠诲姟鏁帮細{}锛岀敓鎴愪换鍔℃暟锛歿}",
+                patids.size(), serviceTask.getTaskid(), deletedCount, generatedCount);
+        return result;
+    }
+
 }
diff --git a/smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml b/smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
index 53aefec..5ea51de 100644
--- a/smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
+++ b/smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
@@ -1655,6 +1655,22 @@
         where patid = #{patid} and taskid = #{taskid}
     </update>
 
+    <!-- 浜哄伐闅忚锛氳蒋鍒犻櫎鎮h�呭嚭闄㈣褰曞搴旂殑鏈畬鎴愰殢璁夸换鍔� -->
+    <update id="deleteUnfinishedServiceSubtaskByInhospids">
+        update service_subtask
+        set del_flag = 1
+        where del_flag = 0
+          and patid = #{patid}
+          and sendstate in
+          <foreach collection="sendstates" item="sendstate" open="(" separator="," close=")">
+              #{sendstate}
+          </foreach>
+          and inhospid in
+          <foreach collection="inhospids" item="inhospid" open="(" separator="," close=")">
+              #{inhospid}
+          </foreach>
+    </update>
+
     <select id="getSfStatistics" parameterType="com.smartor.domain.ServiceSubtaskCountReq"
             resultMap="ServiceSubtaskResult">
         select id,

--
Gitblit v1.9.3