From 599beddc80e7e50b2099bacdbf7df2d89df00ef2 Mon Sep 17 00:00:00 2001
From: 陈昶聿 <chychen@nbjetron.com>
Date: 星期六, 07 十一月 2026 14:42:31 +0800
Subject: [PATCH] fix: 完成时状态与超时判断区分任务组

---
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java |  412 ++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 285 insertions(+), 127 deletions(-)

diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
index 4c9a20d..c1ee902 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -14,6 +14,7 @@
 import com.ruoyi.common.enums.ServiceFromEnum;
 import com.ruoyi.common.utils.*;
 import com.ruoyi.common.utils.http.HttpUtils;
+import com.ruoyi.common.utils.sms.SmsUtils;
 import com.ruoyi.message.SendResult;
 import com.ruoyi.message.sms.SmsSendRequest;
 import com.ruoyi.message.sms.SmsSenderFactory;
@@ -32,6 +33,7 @@
 import com.ruoyi.system.service.ISysUserService;
 import com.ruoyi.message.sms.provider.sltd.ws.MessageSend;
 import com.smartor.common.QwenLLMUtil;
+import com.smartor.common.SpecificArchiveConstants;
 import com.smartor.domain.*;
 import com.ruoyi.task.domain.VO.ServiceSubtaskDetailTraceVO;
 import com.smartor.mapper.*;
@@ -39,6 +41,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.math.NumberUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
@@ -66,8 +69,12 @@
 import com.ruoyi.task.domain.ServiceSubtask;
 import com.ruoyi.task.domain.ServiceSubtaskRecord;
 import com.ruoyi.task.domain.ServiceTask;
+import com.ruoyi.task.domain.ServiceTaskSchedule;
+import com.ruoyi.task.domain.ServiceTaskScheduleDetail;
 import com.ruoyi.task.mapper.ServiceSubtaskMapper;
 import com.ruoyi.task.mapper.ServiceTaskMapper;
+import com.ruoyi.task.mapper.ServiceTaskScheduleMapper;
+import com.ruoyi.task.mapper.ServiceTaskScheduleDetailMapper;
 import com.ruoyi.task.domain.ServiceSubtaskDetailTrace;
 import com.ruoyi.task.domain.VO.ServiceSubtaskDetailTraceVO;
 import com.ruoyi.task.service.IServiceSubtaskDetailTraceService;
@@ -76,6 +83,14 @@
 import com.ruoyi.task.domain.ServiceSubtaskPreachform;
 import com.ruoyi.task.service.IServiceSubtaskService;
 import com.ruoyi.task.domain.SendMagParam;
+import com.ruoyi.task.service.IServiceSubtaskRecordService;
+import com.ruoyi.task.mapper.ServiceSubtaskPreachformMapper;
+import com.ruoyi.patarchive.service.IPatArchiveService;
+import com.ruoyi.datacollection.service.IXHGatherPatArchiveService;
+import com.ruoyi.datacollection.service.IServiceSLTDHealthcareRecordService;
+import com.ruoyi.datacollection.domain.ServiceSLTDInhospReqVO;
+import com.ruoyi.datacollection.domain.ServiceSLTDInhospResDTO;
+
 /**
  * 瀹氭椂浠诲姟璋冨害娴嬭瘯
  *
@@ -156,6 +171,12 @@
 
     @Autowired
     private ServiceSubtaskMapper serviceSubtaskMapper;
+
+    @Autowired
+    private ServiceTaskScheduleMapper serviceTaskScheduleMapper;
+
+    @Autowired
+    private ServiceTaskScheduleDetailMapper serviceTaskScheduleDetailMapper;
 
     @Autowired
     private RedisCache redisCache;
@@ -367,8 +388,7 @@
         //1.鑾峰彇鍙戦�佷汉宸ュ彿
         ServiceSubtaskDetailTraceVO subtaskDetailTraceVO = new ServiceSubtaskDetailTraceVO();
         subtaskDetailTraceVO.setHandleFlag("0");
-        List<ServiceSubtaskDetailTrace> serviceSubtaskDetailTraces =
-                serviceSubtaskDetailTraceService.selectServiceSubtaskDetailTtraceList(subtaskDetailTraceVO);
+        List<ServiceSubtaskDetailTrace> serviceSubtaskDetailTraces = serviceSubtaskDetailTraceService.selectServiceSubtaskDetailTtraceList(subtaskDetailTraceVO);
         // 鑾峰彇鈥滃紓甯稿唴瀹规彁閱�"
         SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique("send.except.content");
         String exceptContent = sysConfig.getConfigValue();
@@ -376,12 +396,12 @@
         // 鑾峰彇鈥滃唴瀹规彁閱掓祴璇曚汉宸ュ彿鈥�
         SysConfig testPersonConfig = sysConfigMapper.checkConfigKeyUnique("send.test.person");
         String testPerson = ObjectUtils.isNotEmpty(testPersonConfig) ? testPersonConfig.getConfigValue() : "";
-        if(CollectionUtils.isNotEmpty(serviceSubtaskDetailTraces)){
+        if (CollectionUtils.isNotEmpty(serviceSubtaskDetailTraces)) {
             for (ServiceSubtaskDetailTrace serviceSubtaskDetailTrace : serviceSubtaskDetailTraces) {
                 List<String> dutyDeptPersonCodeList = new ArrayList<>();
-                        // 鎶� dutyDeptPersonCode 鏁寸悊鍒� list 涓紙濡傛灉澶氫釜浜虹敤閫楀彿鍒嗗壊锛屽垯灞曞紑骞跺幓閲嶏級
+                // 鎶� dutyDeptPersonCode 鏁寸悊鍒� list 涓紙濡傛灉澶氫釜浜虹敤閫楀彿鍒嗗壊锛屽垯灞曞紑骞跺幓閲嶏級
                 String dutyDeptPersonCodeStr = serviceSubtaskDetailTrace.getDutyDeptPersonCode();
-                if(StringUtils.isNotEmpty(dutyDeptPersonCodeStr)){
+                if (StringUtils.isNotEmpty(dutyDeptPersonCodeStr)) {
                     String[] dutyDeptPersonCodeSplit = dutyDeptPersonCodeStr.split(",");
                     if (CollectionUtils.isEmpty(dutyDeptPersonCodeList)) {
                         dutyDeptPersonCodeList = new ArrayList<>(Arrays.asList(dutyDeptPersonCodeSplit));
@@ -409,18 +429,18 @@
                         sysUserVo.setOrgid(serviceSubtaskDetailTrace.getOrgid());
                         List<SysUser> users = userService.getUserList(sysUserVo);
                         String phoneNumber = "";
-                        if(ObjectUtils.isNotEmpty(users)){
+                        if (ObjectUtils.isNotEmpty(users)) {
                             sysUser = users.get(0);
                             phoneNumber = sysUser.getPhonenumber();
-                        }else {
+                        } else {
                             continue;
                         }
 
-                        if(StringUtils.isEmpty(phoneNumber)){
+                        if (StringUtils.isEmpty(phoneNumber)) {
                             continue;
                         }
                         String dutyDeptPerson = dingTalkService.getDingTalkUserByMobile(phoneNumber);
-                        if(StringUtils.isNotBlank(dutyDeptPerson)){
+                        if (StringUtils.isNotBlank(dutyDeptPerson)) {
                             String context = TemplateUtils.render(exceptContent, serviceSubtaskDetailTrace);
                             dingTalkService.sendDingTalkText(context, dutyDeptPerson);
                             //鏇存柊鐘舵��
@@ -566,8 +586,7 @@
             log.error("銆恉ealHisDataMZ銆慡ysConfig涓殑闄㈠尯ID涓虹┖锛�");
             return;
         }
-        List<Long> campusidList = Arrays.stream(sysConfigcampusids.get(0).getConfigValue().split(","))
-                .map(String::trim).filter(StringUtils::isNotBlank).map(Long::valueOf).collect(Collectors.toList());
+        List<Long> campusidList = Arrays.stream(sysConfigcampusids.get(0).getConfigValue().split(",")).map(String::trim).filter(StringUtils::isNotBlank).map(Long::valueOf).collect(Collectors.toList());
         log.info("銆恉ealHisDataMZ銆戦櫌鍖猴細{}锛屽崟杞绠楋細{}鍒嗛挓锛屾瘡椤碉細{}鏉�", campusidList, budgetMinutes, pageSize);
 
         for (Long cid : campusidList) {
@@ -590,15 +609,13 @@
                 redisCache.deleteObject(lockKey);
             }
         }
-        log.info("銆恉ealHisDataMZ銆戦棬鎬ヨ瘖閲囬泦鏈疆缁撴潫锛岃�楁椂锛歿}绉�",
-                java.time.Duration.between(now, LocalDateTime.now()).getSeconds());
+        log.info("銆恉ealHisDataMZ銆戦棬鎬ヨ瘖閲囬泦鏈疆缁撴潫锛岃�楁椂锛歿}绉�", java.time.Duration.between(now, LocalDateTime.now()).getSeconds());
     }
 
     /**
      * 閲囬泦鏌愪釜闄㈠尯锛氬厛琛ヤ竴娆℃�у洖婧棩鏈燂紝鍐嶅仛鏄ㄥぉ鐨勬敹灏鹃噰闆嗭紝鏈�鍚庢暣杞埛鏂颁粖澶�
      */
-    private void collectOutpatientDaily(Long cid, String backfillParam, long pageSize, long maxPage,
-                                        LocalDateTime deadline) {
+    private void collectOutpatientDaily(Long cid, String backfillParam, long pageSize, long maxPage, LocalDateTime deadline) {
         String cursorKey = "mzDayCursor:" + cid;
         MzDayCursor cursor = loadMzDayCursor(cursorKey);
         LocalDate today = LocalDate.now();
@@ -625,8 +642,7 @@
         // 1) 涓�娆℃�у洖婧�
         if (cursor.backfillDay != null) {
             LocalDate day = LocalDate.parse(cursor.backfillDay);
-            MzGatherStatusEnum status = runDayPass(cid, cursorKey, cursor, MzGatherSlotEnum.BACKFILL, day,
-                    cursor.backfillPage, pageSize, maxPage, deadline);
+            MzGatherStatusEnum status = runDayPass(cid, cursorKey, cursor, MzGatherSlotEnum.BACKFILL, day, cursor.backfillPage, pageSize, maxPage, deadline);
             if (status != MzGatherStatusEnum.DONE) {
                 log.warn("銆恉ealHisDataMZ銆戝洖婧棩鏈� {} 鏈疆鏈畬鎴愶紙{}锛夛紝鏂偣宸蹭繚鐣欙紝闄㈠尯锛歿}", day, status.getDesc(), cid);
                 return;
@@ -639,8 +655,7 @@
 
         // 2) 鏄ㄥぉ鏀跺熬閲囬泦锛氭瘡澶╀竴娆★紝鍏滀綇 23:xx 涔嬪悗鎵嶅啓杩� HIS 鐨勮褰曞拰璺ㄩ浂鐐圭殑鏁版嵁
         if (!yesterday.toString().equals(cursor.finalDay)) {
-            MzGatherStatusEnum status = runDayPass(cid, cursorKey, cursor, MzGatherSlotEnum.FINAL, yesterday,
-                    cursor.finalPage, pageSize, maxPage, deadline);
+            MzGatherStatusEnum status = runDayPass(cid, cursorKey, cursor, MzGatherSlotEnum.FINAL, yesterday, cursor.finalPage, pageSize, maxPage, deadline);
             if (status != MzGatherStatusEnum.DONE) {
                 log.warn("銆恉ealHisDataMZ銆戞槰鏃ユ敹灏鹃噰闆� {} 鏈疆鏈畬鎴愶紙{}锛夛紝鏂偣宸蹭繚鐣欙紝闄㈠尯锛歿}", yesterday, status.getDesc(), cid);
                 return;
@@ -656,8 +671,7 @@
             cursor.page = 1L;
             saveMzDayCursor(cursorKey, cursor);
         }
-        MzGatherStatusEnum status = runDayPass(cid, cursorKey, cursor, MzGatherSlotEnum.TODAY, today,
-                cursor.page, pageSize, maxPage, deadline);
+        MzGatherStatusEnum status = runDayPass(cid, cursorKey, cursor, MzGatherSlotEnum.TODAY, today, cursor.page, pageSize, maxPage, deadline);
         if (status == MzGatherStatusEnum.DONE) {
             // 鏁磋疆鍒锋柊瀹屾垚锛岄〉鐮佸綊浣嶏紝涓嬩竴杞噸鏂颁粠绗竴椤垫暣杞埛鏂�
             cursor.page = 1L;
@@ -672,9 +686,7 @@
      * @param slot 鏂偣妲戒綅锛堜粖澶╂暣杞埛鏂� / 鏄ㄦ棩鏀跺熬 / 鎵嬪伐鍥炴函锛夛紝鍐冲畾涓柇椤电爜璁板埌鍝釜瀛楁
      * @return {@link MzGatherStatusEnum} 閲囬泦瀹屾垚 / 棰勭畻鐢ㄥ敖 / 鎺ュ彛杩炵画澶辫触鎻愬墠缁撴潫
      */
-    private MzGatherStatusEnum runDayPass(Long cid, String cursorKey, MzDayCursor cursor, MzGatherSlotEnum slot,
-                                          LocalDate day, long startPage, long pageSize, long maxPage,
-                                          LocalDateTime deadline) {
+    private MzGatherStatusEnum runDayPass(Long cid, String cursorKey, MzDayCursor cursor, MzGatherSlotEnum slot, LocalDate day, long startPage, long pageSize, long maxPage, LocalDateTime deadline) {
         String startStr = day.format(MzGatherConstant.DAY_FMT);
         String endStr = day.plusDays(1).format(MzGatherConstant.DAY_FMT);
 
@@ -705,8 +717,7 @@
                 // 鏈疆鏈夎烦杩囩殑椤垫椂锛屾柇鐐瑰洖鍒扮涓�涓け璐ラ〉锛屼繚璇佷笅涓�杞厛鎶婅繖浜涢〉琛ュ洖鏉�
                 long resumePage = (skippedPages > 0 && firstFailPage > 0) ? firstFailPage : page;
                 saveMzDayPage(cursorKey, cursor, slot, resumePage);
-                log.warn("銆恉ealHisDataMZ銆戞湰杞椂闂撮绠楃敤灏斤紝{} 鏈疆宸查噰{}椤祘}鏉}锛屼笅娆′粠绗瑊}椤电户缁紝闄㈠尯锛歿}",
-                        day, pageCount, total, skippedLog(skippedPages), resumePage, cid);
+                log.warn("銆恉ealHisDataMZ銆戞湰杞椂闂撮绠楃敤灏斤紝{} 鏈疆宸查噰{}椤祘}鏉}锛屼笅娆′粠绗瑊}椤电户缁紝闄㈠尯锛歿}", day, pageCount, total, skippedLog(skippedPages), resumePage, cid);
                 return MzGatherStatusEnum.BUDGET_UP;
             }
             reqVO.setCurrent(page);
@@ -740,13 +751,10 @@
                     firstFailPage = page;
                 }
                 consecutiveFail++;
-                log.error("銆恉ealHisDataMZ銆戞帴鍙e眰閲囬泦澶辫触锛屽凡璁� error 鏃ュ織骞惰烦杩囪椤碉紝鏈疆缁х画寰�鍚庨噰锛�"
-                                + "闄㈠尯锛歿}锛屾棩鏈燂細{}锛岀{}椤碉紝鎺ュ彛鍏ュ弬锛歿}锛屽紓甯革細{}",
-                        cid, day, page, new Gson().toJson(reqVO), lastError.getMessage(), lastError);
+                log.error("銆恉ealHisDataMZ銆戞帴鍙e眰閲囬泦澶辫触锛屽凡璁� error 鏃ュ織骞惰烦杩囪椤碉紝鏈疆缁х画寰�鍚庨噰锛�" + "闄㈠尯锛歿}锛屾棩鏈燂細{}锛岀{}椤碉紝鎺ュ彛鍏ュ弬锛歿}锛屽紓甯革細{}", cid, day, page, new Gson().toJson(reqVO), lastError.getMessage(), lastError);
                 if (consecutiveFail >= MzGatherConstant.MAX_CONSECUTIVE_PAGE_FAIL) {
                     // 杩炵画澶氶〉鎺ュ彛澶辫触锛屽垽瀹氭潵鏈潵鎺ュ彛鏁翠綋涓嶅彲鐢紝鏈疆鎻愬墠缁撴潫锛堜笉鍐嶇┖杞悗闈㈠嚑鍗侀〉锛夛紝鏂偣鐣欏湪绗竴涓け璐ラ〉
-                    log.error("銆恉ealHisDataMZ銆戣繛缁瓄}椤垫帴鍙eけ璐ワ紝鍒ゅ畾鏉ユ湭鏉ユ帴鍙d笉鍙敤锛屾湰杞彁鍓嶇粨鏉燂紱闄㈠尯锛歿}锛屾棩鏈燂細{}锛屾柇鐐逛繚鐣欏湪绗瑊}椤�",
-                            consecutiveFail, cid, day, firstFailPage);
+                    log.error("銆恉ealHisDataMZ銆戣繛缁瓄}椤垫帴鍙eけ璐ワ紝鍒ゅ畾鏉ユ湭鏉ユ帴鍙d笉鍙敤锛屾湰杞彁鍓嶇粨鏉燂紱闄㈠尯锛歿}锛屾棩鏈燂細{}锛屾柇鐐逛繚鐣欏湪绗瑊}椤�", consecutiveFail, cid, day, firstFailPage);
                     saveMzDayPage(cursorKey, cursor, slot, firstFailPage);
                     return MzGatherStatusEnum.FAILED;
                 }
@@ -756,8 +764,7 @@
             consecutiveFail = 0;
 
             if (CollectionUtils.isEmpty(pageData)) {
-                log.info("銆恉ealHisDataMZ銆憑} 绗瑊}椤垫棤鏁版嵁锛岄噰闆嗙粨鏉燂紝闄㈠尯锛歿}锛屾湰杞畕}椤靛叡{}鏉}",
-                        day, page, cid, pageCount, total, skippedLog(skippedPages));
+                log.info("銆恉ealHisDataMZ銆憑} 绗瑊}椤垫棤鏁版嵁锛岄噰闆嗙粨鏉燂紝闄㈠尯锛歿}锛屾湰杞畕}椤靛叡{}鏉}", day, page, cid, pageCount, total, skippedLog(skippedPages));
                 return MzGatherStatusEnum.DONE;
             }
             pageCount++;
@@ -777,7 +784,9 @@
         }
     }
 
-    /** 鎸夋Ы浣嶄繚瀛樹腑鏂〉鐮� */
+    /**
+     * 鎸夋Ы浣嶄繚瀛樹腑鏂〉鐮�
+     */
     private void saveMzDayPage(String cursorKey, MzDayCursor cursor, MzGatherSlotEnum slot, long page) {
         if (slot == MzGatherSlotEnum.FINAL) {
             cursor.finalPage = page;
@@ -789,12 +798,16 @@
         saveMzDayCursor(cursorKey, cursor);
     }
 
-    /** 鏃ュ織閲屾彁绀烘帴鍙e眰澶辫触璺宠繃浜嗗嚑椤碉紙涓嬩竴杞暣杞埛鏂颁細閲嶆柊閲囧埌锛� */
+    /**
+     * 鏃ュ織閲屾彁绀烘帴鍙e眰澶辫触璺宠繃浜嗗嚑椤碉紙涓嬩竴杞暣杞埛鏂颁細閲嶆柊閲囧埌锛�
+     */
     private String skippedLog(long skippedPages) {
         return skippedPages > 0L ? "锛屾帴鍙eけ璐ヨ烦杩�" + skippedPages + "椤碉紙涓嬩竴杞暣杞埛鏂颁細閲嶆柊閲囧埌锛�" : "";
     }
 
-    /** 璇诲彇 sys_config 閲岀殑闂ㄦ�ヨ瘖閲囬泦鍙傛暟锛堟満鏋� orgid=20001001锛夛紝鍙栦笉鍒版垨瓒呰寖鍥存椂鐢ㄦ灇涓鹃噷鐨勯粯璁ゅ�� */
+    /**
+     * 璇诲彇 sys_config 閲岀殑闂ㄦ�ヨ瘖閲囬泦鍙傛暟锛堟満鏋� orgid=20001001锛夛紝鍙栦笉鍒版垨瓒呰寖鍥存椂鐢ㄦ灇涓鹃噷鐨勯粯璁ゅ��
+     */
     private long getMzConfigLong(MzGatherParamEnum param) {
         try {
             SysConfig config = new SysConfig();
@@ -806,8 +819,7 @@
                 if (value >= param.getMin() && value <= param.getMax()) {
                     return value;
                 }
-                log.warn("銆恉ealHisDataMZ銆戦厤缃畕}鐨勫�納}瓒呭嚭鑼冨洿[{},{}]锛屼娇鐢ㄩ粯璁ゅ�納}",
-                        param.getKey(), value, param.getMin(), param.getMax(), param.getDefaultValue());
+                log.warn("銆恉ealHisDataMZ銆戦厤缃畕}鐨勫�納}瓒呭嚭鑼冨洿[{},{}]锛屼娇鐢ㄩ粯璁ゅ�納}", param.getKey(), value, param.getMin(), param.getMax(), param.getDefaultValue());
             }
         } catch (Exception e) {
             log.warn("銆恉ealHisDataMZ銆戣鍙栭厤缃畕}澶辫触锛屼娇鐢ㄩ粯璁ゅ�納}", param.getKey(), param.getDefaultValue(), e);
@@ -815,7 +827,9 @@
         return param.getDefaultValue();
     }
 
-    /** 瑙f瀽浠诲姟鍏ュ弬锛堣涓�娆℃�у洖婧殑鏃ユ湡锛夛紝鏀寔 yyyy-MM-dd HH:mm:ss 涓� yyyy-MM-dd */
+    /**
+     * 瑙f瀽浠诲姟鍏ュ弬锛堣涓�娆℃�у洖婧殑鏃ユ湡锛夛紝鏀寔 yyyy-MM-dd HH:mm:ss 涓� yyyy-MM-dd
+     */
     private LocalDateTime parseMzStartTime(String text) {
         LocalDateTime time = parseMzTimeQuiet(text);
         if (time == null && StringUtils.isNotBlank(text)) {
@@ -824,7 +838,9 @@
         return time;
     }
 
-    /** 闈欓粯瑙f瀽鏃ユ湡锛屾敮鎸� yyyy-MM-dd HH:mm:ss 涓� yyyy-MM-dd锛屾牸寮忎笉绗﹁繑鍥� null锛堜笉鍒锋棩蹇楋級 */
+    /**
+     * 闈欓粯瑙f瀽鏃ユ湡锛屾敮鎸� yyyy-MM-dd HH:mm:ss 涓� yyyy-MM-dd锛屾牸寮忎笉绗﹁繑鍥� null锛堜笉鍒锋棩蹇楋級
+     */
     private LocalDateTime parseMzTimeQuiet(String text) {
         if (StringUtils.isBlank(text)) {
             return null;
@@ -842,7 +858,9 @@
         }
     }
 
-    /** 淇濆瓨闂ㄦ�ヨ瘖閲囬泦鏂偣锛堝悇杞涓柇鐨勯〉鐮侊級 */
+    /**
+     * 淇濆瓨闂ㄦ�ヨ瘖閲囬泦鏂偣锛堝悇杞涓柇鐨勯〉鐮侊級
+     */
     private void saveMzDayCursor(String cursorKey, MzDayCursor cursor) {
         JSONObject json = new JSONObject();
         json.put("day", cursor.day);
@@ -856,7 +874,9 @@
         redisCache.setCacheObject(cursorKey, json.toJSONString(), MzGatherConstant.CACHE_TTL_HOURS, TimeUnit.HOURS);
     }
 
-    /** 璇诲彇闂ㄦ�ヨ瘖閲囬泦鏂偣锛岃涓嶅埌鎴栬В鏋愬け璐ユ椂杩斿洖绌烘柇鐐癸紙绛変环浜庝粠绗竴椤靛紑濮嬫暣杞埛鏂帮級 */
+    /**
+     * 璇诲彇闂ㄦ�ヨ瘖閲囬泦鏂偣锛岃涓嶅埌鎴栬В鏋愬け璐ユ椂杩斿洖绌烘柇鐐癸紙绛変环浜庝粠绗竴椤靛紑濮嬫暣杞埛鏂帮級
+     */
     private MzDayCursor loadMzDayCursor(String cursorKey) {
         MzDayCursor cursor = new MzDayCursor();
         try {
@@ -893,16 +913,24 @@
      * 锛堥〉鐮佷负 1 琛ㄧず璇ヨ疆娆′笅涓�杞粠绗竴椤垫暣杞紑濮嬶級
      */
     private static class MzDayCursor {
-        /** 浠婂ぉ鐨勬暣杞埛鏂� */
+        /**
+         * 浠婂ぉ鐨勬暣杞埛鏂�
+         */
         private String day;
         private long page = 1L;
-        /** 鏄ㄥぉ鐨勬敹灏鹃噰闆� */
+        /**
+         * 鏄ㄥぉ鐨勬敹灏鹃噰闆�
+         */
         private String finalDay;
         private long finalPage = 1L;
-        /** 寰呭仛鐨勪竴娆℃�у洖婧� */
+        /**
+         * 寰呭仛鐨勪竴娆℃�у洖婧�
+         */
         private String backfillDay;
         private long backfillPage = 1L;
-        /** 宸茬粡琛ヨ繃鐨勫洖婧棩鏈燂紝閬垮厤瀹氭椂浠诲姟姣忚疆閲嶅琛ュ悓涓�澶� */
+        /**
+         * 宸茬粡琛ヨ繃鐨勫洖婧棩鏈燂紝閬垮厤瀹氭椂浠诲姟姣忚疆閲嶅琛ュ悓涓�澶�
+         */
         private String backfillDone;
     }
 
@@ -1036,8 +1064,10 @@
      * 澶勭悊鎮h�呬俊鎭紝杩涘叆瀛愪换鍔¤〃(浠诲姟缁�)
      * <p>
      * 鈿狅笍 2025 淇锛堝紑鍏冲け鏁堬級锛氬師璧� smartor 閬楃暀瀹炵幇锛屼笉鍒ゅ紑鍏筹紙鍚� {@link #dealOutHospInfo()}锛夈��
-     * 鐜拌蛋妯″潡闂ㄩ潰銆傛敞鎰忔ā鍧椾晶鐨� {@code dealOutHospInfoBySchedule} 鍐呴儴浠嶄細杞彂鍥� smartor
-     * 锛坽@code OtherVisitApiBridge}锛岃璇ョ被娉ㄩ噴锛夛紝浣�<b>寮�鍏冲湪闂ㄩ潰杩欎竴灞傚垽</b>锛屾墍浠ュ叧闂椂涓嶄細璧板埌閭i噷銆�
+     * 鐜拌蛋妯″潡闂ㄩ潰銆傛ā鍧椾晶 {@code dealOutHospInfoBySchedule} 缁� {@code OtherVisitApi} 濂戠害
+     * 鍥炶皟 {@code ruoyi-task/api/contract/OtherVisitApiImpl}锛�2026-11 璧峰疄鐜版暣绨囨惉杩� task 妯″潡锛�
+     * smartor 渚х殑 {@code OtherVisitApiBridge} 宸插垹闄わ級锛屼絾<b>寮�鍏冲湪闂ㄩ潰杩欎竴灞傚垽</b>锛�
+     * 鎵�浠ュ叧闂椂涓嶄細璧板埌閭i噷銆�
      */
     public void dealOutHospInfoBySchedule() {
         String config = configService.selectConfigByKey("visit.early.day");
@@ -1132,6 +1162,13 @@
             serviceSubtaskList.addAll(compensateServiceSubtaskList);
         }
         for (ServiceSubtask serviceSubtask : serviceSubtaskList) {
+            //currentPreachform涓虹┖锛岃鏄庤瀛愪换鍔¤繕娌℃湁鎵ц杩囦换浣曚竴绉嶅彂閫佹柟寮�(sendstate=1锛屽睘浜庨娆¤ˉ鍋�)锛�
+            //杩欓噷鐩存帴浜ょ粰sfHandlle澶勭悊锛屽畠浼氭寜sort=1鐨勭涓�绉嶅彂閫佹柟寮忓彂閫侊紝涓巊etSendPreachform涓殑澶勭悊淇濇寔涓�鑷�
+            if (StringUtils.isEmpty(serviceSubtask.getCurrentPreachform())) {
+                log.warn("銆恈ompensateTask銆憇ubid锛歿}锛宑urrentPreachform涓虹┖锛屾寜绗竴绉嶅彂閫佹柟寮忚ˉ鍋垮鐞�", serviceSubtask.getId());
+                sfHandlle(serviceSubtask);
+                continue;
+            }
             //鏍规嵁褰撳墠鐨勬墽琛屾柟寮忥紝鑾峰彇涓嬩竴绉嶆墽琛屾柟寮�
             ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
             serviceSubtaskPreachform.setTaskid(serviceSubtask.getTaskid());
@@ -1142,6 +1179,25 @@
             Optional<Long> currentSort = serviceSubtaskPreachforms.stream().filter(item -> serviceSubtask.getCurrentPreachform().equals(item.getPreachform())).map(ServiceSubtaskPreachform::getSort).findFirst();
             Optional<Long> id = serviceSubtaskPreachforms.stream().filter(item -> serviceSubtask.getCurrentPreachform().equals(item.getPreachform())).map(ServiceSubtaskPreachform::getId).findFirst();
             if (currentSort.isPresent()) {
+                // 鏂规B锛氬彧澶勭悊褰撳墠瀛愪换鍔♀�斺�斿叕浼楀彿宸查鍙�(service_subtask.sendstate=1 + current_preachform=5)
+                // 涓旀湭濉啓鏃讹紝鎸夐粯璁ら�夐」瀹屾垚锛岄伩鍏嶈繘鍏ヤ笅涓�绉嶅彂閫佹柟寮忔垨鏈�鍚庝竴姝ヨ秴鏃躲��
+                // 鍏堢敤鍐呭瓨瀛楁蹇�熻繃婊わ紝鍏朵粬鍖婚櫌/浠诲姟/鍙戦�佹柟寮忎笉浼氳繘鍏ヤ笅闈㈢殑榛樿瀹屾垚閫昏緫銆�
+                if (IServiceSubtaskService.WECHAT_DEFAULT_COMPLETE_ORGID.equals(serviceSubtask.getOrgid())
+                        && "2".equals(serviceSubtask.getType())
+                        && "5".equals(serviceSubtask.getCurrentPreachform())
+                        && Long.valueOf(1L).equals(serviceSubtask.getSendstate())
+                        && !Long.valueOf(1L).equals(serviceSubtask.getSubmit())) {
+                    try {
+                        if (iServiceSubtaskService.completeWechatClaimedByDefault(serviceSubtask)) {
+                            log.info("銆恈ompensateTask銆憇ubid锛歿}锛屽井淇″叕浼楀彿宸查鍙栨湭濉啓锛屾寜榛樿閫夐」瀹屾垚", serviceSubtask.getId());
+                            continue;
+                        }
+                    } catch (Exception e) {
+                        // 鍗曚釜瀛愪换鍔″け璐ヤ笉褰卞搷鍏朵粬浠诲姟锛屽洖婊氬悗缁х画鍘熻ˉ鍋挎祦绋�
+                        log.error("銆恈ompensateTask銆戝井淇″叕浼楀彿榛樿瀹屾垚澶辫触锛宻ubid锛歿}锛岀户缁師琛ュ伩娴佺▼", serviceSubtask.getId(), e);
+                    }
+                }
+
                 //1鍏堟鏌ヤ竴涓嬶紝鏄笉鏄湁鎵ц鐘舵�佹槸瀹屾垚鐨勶紙鎬曚箣鍓嶅凡缁忔湁瀹岀殑浜嗭紝娌℃湁灏唖ervuce_subtask鐨勭姸鎬佹敼鎴愬姛锛岃繖閲屽啀妫�鏌ヤ竴涓嬶級
                 boolean finishState = serviceSubtaskPreachforms.stream().allMatch(item -> item.getSendstate().equals("9"));
                 if (finishState) {
@@ -1153,8 +1209,7 @@
                 //2鍒ゆ柇涓�涓嬶紝褰撳墠鐨剆ort鏄笉鏄瓑浜庨渶瑕佹墽琛岀殑鎬讳釜鏁帮紝濡傛灉绛変簬鐨勮瘽锛岃鏄庢槸鏈�鍚庝竴涓紝鐩存帴灏唖ervuce_subtask鐨勭姸鎬佹敼鎴�5锛屾墽琛屽け璐ュ氨琛屼簡
                 Long cs = currentSort.get();
 
-                if (cs.equals(serviceSubtaskPreachforms.size())
-                        && isSubtaskDeadline(serviceSubtask, serviceSubtaskPreachforms)) {
+                if (cs.equals(serviceSubtaskPreachforms.size()) && isSubtaskDeadline(serviceSubtask, serviceSubtaskPreachforms)) {
                     serviceSubtask.setSendstate(7L);
                     serviceSubtask.setRemark("澶勭悊琛ュ伩浠诲姟,褰撳墠澶勭悊鏈�鍚庤ˉ鍋匡紝鍏ㄩ儴鎵ц澶辫触锛堣秴鏃讹級");
 
@@ -1204,6 +1259,24 @@
     }
 
     /**
+     * 鎸夋満鏋勬煡璇㈤厤缃�硷紙鍚屼竴 key 鍦ㄤ笉鍚屾満鏋勪笅鍙厤缃笉鍚屽�硷級
+     *
+     * @param configKey 閰嶇疆key
+     * @param orgid     鏈烘瀯ID
+     * @return 閰嶇疆鍊硷紝鏈厤缃繑鍥� null
+     */
+    private String getConfigValue(String configKey, String orgid) {
+        SysConfig query = new SysConfig();
+        query.setConfigKey(configKey);
+        query.setOrgid(orgid);
+        List<SysConfig> sysConfigs = configService.selectConfigList(query);
+        if (CollectionUtils.isNotEmpty(sysConfigs)) {
+            return sysConfigs.get(0).getConfigValue();
+        }
+        return null;
+    }
+
+    /**
      * 闅忚-琛ュ伩澶勭悊
      *
      * @param serviceSubtask
@@ -1217,6 +1290,7 @@
         serviceSubtaskPreachform.setSubid(serviceSubtask.getId());
         //鑾峰彇鍙戦�佹柟寮�
         String sendPreachform = getSendPreachform(serviceSubtaskPreachform, serviceSubtask);
+        log.info("sendPreachform鐨勫彂閫佹柟寮忔槸鍟ワ細{}", sendPreachform);
         if (sendPreachform.equals("-1") || serviceSubtask.getSendstate() == 6 || serviceSubtask.getSendstate() == 5 || serviceSubtask.getSendstate() == 4) {
             //璇存槑宸茬粡鍏ㄩ儴閬嶅巻瀹屼簡锛屽綋鍓嶇殑鎵ц鏂瑰紡搴忓彿鏄渶鍚庝竴涓簡   鎴栬��  璇ユ偅鑰呭凡缁忛殢璁跨粨鏉燂紙鎴愬姛鎴栧け璐ヤ簡鎴栦笉鎵ц锛�
             log.error("璇存槑宸茬粡鍏ㄩ儴閬嶅巻瀹屼簡锛屽綋鍓嶇殑鎵ц鏂瑰紡搴忓彿鏄渶鍚庝竴涓簡   鎴栬��  璇ユ偅鑰呭凡缁忛殢璁跨粨鏉燂紙鎴愬姛鎴栧け璐ヤ簡鎴栦笉鎵ц锛�");
@@ -1224,6 +1298,7 @@
         }
         //鍏堝垽鏂偅鑰呮槸涓嶆槸杩樿鍙戦��
         PatArchive patArchive = patArchiveService.selectPatArchiveByPatid(serviceSubtask.getPatid());
+        log.info("patArchive鐨勫�间负锛歿}", patArchive);
         if (!Objects.isNull(patArchive) && patArchive.getNotrequiredFlag() == "1") {
             //涓嶉渶瑕佸彂閫�
             serviceSubtask.setResult("鎮h�呬笉闇�瑕侀殢璁�");
@@ -1247,8 +1322,7 @@
         // 鍦ㄥ紑鍏虫仮澶嶅悗姘歌繙涓㈠け銆備繚鎸� sendstate 涓嶅姩锛屽紑鍏虫墦寮�鍚庝笅涓�娆� longTaskSend/compensateTask
         // 浼氱収甯告妸瀹冩崬鍑烘潵鍙戝嚭銆�
         if ("3".equals(serviceSubtask.getType()) && !publicityFacade.isEnabled()) {
-            log.warn("銆愬鏁欍�戞ā鍧楁湭鍚敤锛堝弬鏁伴厤缃� publicity.enabled=false锛夛紝璺宠繃瀹f暀鍙戦�併�俿ubtaskId={}, patid={}",
-                    serviceSubtask.getId(), serviceSubtask.getPatid());
+            log.warn("銆愬鏁欍�戞ā鍧楁湭鍚敤锛堝弬鏁伴厤缃� publicity.enabled=false锛夛紝璺宠繃瀹f暀鍙戦�併�俿ubtaskId={}, patid={}", serviceSubtask.getId(), serviceSubtask.getPatid());
             return;
         }
 
@@ -1335,8 +1409,9 @@
                     serviceOutPath.setOrgid(serviceSubtask.getOrgid());
                     iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                     String url = "";
-                    String format = String.format("%03X", serviceOutPath.getId());
+                    String format = ShortCode.encode(serviceOutPath.getId());
                     //鍏堝垽鏂竴涓嬪彂鐨勬槸涓嶆槸瀹f暀
+                    log.info("serviceSubtask.getType鐨勫�间负锛歿}", serviceSubtask.getType());
                     if (!"3".equals(serviceSubtask.getType())) {
                         sendMagParam.setPhone(serviceSubtask.getPhone());
                         url = StringUtils.isNotEmpty(req_path) ? localIP + ":" + req_path + "/wt?p=" + format : localIP + "/wt?p=" + format;
@@ -1344,7 +1419,7 @@
                         //濡傛灉type鏄闊抽殢璁跨殑璇濓紙璇存槑琛ュ伩鍙戦�佹柟寮忎腑鏈夌數璇濋殢璁跨殑鏂瑰紡锛岃繖閲岀殑澶栭摼灏卞湴鍧�鍙兘鐢�/sf锛�
                         if (serviceSubtask.getType().equals("1"))
                             url = StringUtils.isNotEmpty(req_path) ? localIP + ":" + req_path + "/sf?p=" + format : localIP + "/sf?p=" + format;
-                            sendMagParam.setUrl(url);
+                        sendMagParam.setUrl(url);
 
 //                        SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique("wj.sms.template");
                         SysConfig sysConfig = new SysConfig();
@@ -1355,7 +1430,8 @@
                         } else {
                             sysConfig = sysConfigMapper.checkConfigKeyUnique("wj.sms.template");
                         }
-                        if (!Objects.isNull(sysConfig)) {
+                        log.info("sysConfig鐨勫�间负锛歿}", sysConfig);
+                        if (!Objects.isNull(sysConfig) && StringUtils.isNotEmpty(sysConfig.getConfigValue())) {
                             String smsContemt = sysConfig.getConfigValue();
 //                            sendMagParam.setContent("鎮ㄥソ锛岄個璇锋偍濉啓鍑洪櫌璋冩煡琛紝璇风偣鍑�" + sendMagParam.getUrl() + "濉啓銆傛劅璋㈡偍閰嶅悎锛�");
                             sendMagParam.setContent(smsContemt.replace("${wjurl}", sendMagParam.getUrl()));
@@ -1375,7 +1451,7 @@
                             sendMagParam.setUrl(url);
 
                             SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique("xj.sms.template");
-                            if (!Objects.isNull(sysConfig)) {
+                            if (!Objects.isNull(sysConfig) && StringUtils.isNotEmpty(sysConfig.getConfigValue())) {
                                 String smsContemt = sysConfig.getConfigValue();
 //                              sendMagParam.setContent("鎮ㄥソ锛岄個璇锋偍濉啓鍑洪櫌瀹f暀璋冩煡琛紝璇风偣鍑�" + sendMagParam.getUrl() + "鏌ョ湅銆傛劅璋㈡偍閰嶅悎锛�");
                                 sendMagParam.setContent(smsContemt.replace("${xjurl}", sendMagParam.getUrl()));
@@ -1391,6 +1467,13 @@
 
                     }
 
+                    //鍐呭涓虹┖璇存槑鐭俊妯℃澘鏈厤缃垨瀹f暀/閫氱煡鍐呭涓虹┖锛岀洿鎺ユ寜鍙戦�佸け璐ュ鐞嗭紝閬垮厤鍚庣画鍙戦�佹椂鍑虹幇绌烘寚閽�
+                    if (StringUtils.isEmpty(sendMagParam.getContent())) {
+                        log.error("銆恠fHandlle銆戦暱鏈熶换鍔$煭淇″唴瀹逛负绌猴紝鏃犳硶鍙戦�侊紝subid锛歿}锛宼askid锛歿}锛宼ype锛歿}锛屾満鏋処D锛歿}", serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getType(), serviceSubtask.getOrgid());
+                        setSuccessPreachForm(serviceSubtask, sendPreachform, "闀挎湡浠诲姟鐭俊鍙戦�佸け璐�:鐭俊鍐呭涓虹┖(鐭俊妯℃澘鏈厤缃垨鍐呭涓虹┖), 鏃堕棿: " + now, "5");
+                        return;
+                    }
+
                     serviceOutPath.setRadix(format);
                     serviceOutPath.setUpdateTime(new Date());
                     serviceOutPath.setUrl(url);
@@ -1398,8 +1481,24 @@
                     //鐭俊鍙戦�侊細鍚勭珯鐐瑰鎺ユ柟寮忓樊寮傝緝澶э紙鎶ユ枃/绛惧悕/token/杩斿洖鍒ゅ畾閮戒笉鍚岋級锛�
                     //宸叉敹鍙e埌 ruoyi-message 妯″潡锛岃繖閲屽彧璐熻矗缁勮鍏ュ弬骞惰矾鐢�
                     log.info("active鐨勫�间负锛歿}", active);
-                    SendResult smsSendResult = sendSmsByActive(serviceSubtask, sendMagParam);
-                    String isSuccess = smsSendResult.asLegacyFlag();
+                    String isSuccess = "";
+                    if ("ls".equals(active) && "47226079133110211G1001".equals(serviceSubtask.getOrgid())) {
+                        //涓芥按濡囧辜璧颁腑鍥界Щ鍔ㄤ簯MAS锛屼笉渚濊禆 ls.msg.info 涓� token锛�
+                        //ruoyi-message 鐨� ls 閫氶亾灏氭湭瑕嗙洊浜慚AS锛屾晠姝ゅ淇濈暀 SmsUtils 鐩磋繛
+                        SmsUtils.YunMasConfig yunMasConfig = SmsUtils.YunMasConfig.of(getConfigValue("ls.msg.yunmas", serviceSubtask.getOrgid()));
+                        SmsUtils.SmsResult yunMasSmsResult = SmsUtils.sendYunMasSms(yunMasConfig, sendMagParam.getPhone(), sendMagParam.getContent());
+                        log.info("銆恠fHandlle銆戜簯MAS鐭俊鍙戦�佺粨鏋滐細ok={}锛宺spcod={}锛宮sgGroup={}锛宮essage={}",
+                                yunMasSmsResult.isOk(), yunMasSmsResult.getRspcod(), yunMasSmsResult.getMsgGroup(), yunMasSmsResult.getMessage());
+                        isSuccess = yunMasSmsResult.isOk() ? "true" : "false";
+                        if (!yunMasSmsResult.isOk()) {
+                            log.error("銆恠fHandlle銆戜簯MAS鐭俊鍙戦�佸け璐ワ紝subid锛歿}锛屾墜鏈哄彿锛歿}锛屽師鍥狅細{}",
+                                    serviceSubtask.getId(), sendMagParam.getPhone(), yunMasSmsResult.getMessage());
+                        }
+                    } else {
+                        SendResult smsSendResult = sendSmsByActive(serviceSubtask, sendMagParam);
+                        log.info("smsSendResult鐨勫�间负锛歿}", smsSendResult);
+                        isSuccess = smsSendResult.asLegacyFlag();
+                    }
                     //浠诲姟鍙戦�佽褰�
                     ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                     serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
@@ -1414,6 +1513,7 @@
                     serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
 
                     //鍙戦�佸畬鎴愬悗锛屼慨鏀圭姸鎬�
+                    log.info("serviceSubtaskRecord鐨勫�间负锛歿}", serviceSubtaskRecord);
                     serviceSubtask.setSendstate(3L);
                     if (StringUtils.isNotEmpty(isSuccess) && isSuccess.equals("true")) {
                         serviceSubtask.setResult("success");
@@ -1452,7 +1552,7 @@
                     serviceOutPath.setCreateTime(new Date());
                     serviceOutPath.setOrgid(serviceSubtask.getOrgid());
                     iServiceOutPathService.insertServiceOutPath(serviceOutPath);
-                    String format = String.format("%03X", serviceOutPath.getId());
+                    String format = ShortCode.encode(serviceOutPath.getId());
                     serviceOutPath.setRadix(format);
                     serviceOutPath.setUpdateTime(new Date());
                     serviceOutPath.setUrl(url);
@@ -1466,6 +1566,7 @@
                     //浠诲姟鍙戦�佽褰�
                     ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                     serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
+                    serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
                     serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
                     serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
                     serviceSubtaskRecord.setPreachform("4");
@@ -1546,10 +1647,10 @@
     private String resolveShiyiCampus(ServiceSubtask serviceSubtask) {
         SysDept sysDeptVo = new SysDept();
         List<SysDept> sysDepts = new ArrayList<>();
-        if (ObjectUtils.isNotEmpty(serviceSubtask.getDeptcode())) {
+        if (ObjectUtils.isNotEmpty(serviceSubtask.getLeaveldeptcode())) {
             sysDeptVo.setDeptType("1");
             sysDeptVo.setOrgid(serviceSubtask.getOrgid());
-            sysDeptVo.setDeptCode(serviceSubtask.getDeptcode());
+            sysDeptVo.setDeptCode(serviceSubtask.getLeaveldeptcode());
             sysDeptService.selectDeptList(sysDeptVo);
         } else if (ObjectUtils.isNotEmpty(serviceSubtask.getLeavehospitaldistrictcode())) {
             sysDeptVo.setDeptType("2");
@@ -1617,8 +1718,7 @@
                 return "-1";
             }
             // 褰搒ort绛変簬鍒楄〃size鏃讹紝骞朵笖鎵�鏈塻endstate閮戒笉绛変簬9锛屽垯杩斿洖-1
-            if (currentSort.get().equals((long) serviceSubtaskPreachforms.size())
-                    && isSubtaskDeadline(serviceSubtask, serviceSubtaskPreachforms)) {
+            if (currentSort.get().equals((long) serviceSubtaskPreachforms.size()) && isSubtaskDeadline(serviceSubtask, serviceSubtaskPreachforms)) {
                 if (allSendStateNot1AndNot9) {
                     //璇存槑鍏ㄥ彂閫佸け璐ヤ簡
                     serviceSubtask.setSendstate(7L);
@@ -1710,6 +1810,25 @@
         }
     }
 
+    /**
+     * 閲囬泦涓芥按甯傚骞间繚鍋ラ櫌闂ㄨ瘖鎺ヨ瘖瀹屾垚璁板綍锛屽苟鎸夐厤缃敓鎴愬绉�/鍎跨妗f銆�
+     * 瀹氭椂浠诲姟榛樿閲囬泦鏄ㄥぉ 00:00:00 ~ 浠婂ぉ 00:00:00銆�
+     */
+    public void collectMchArchive() {
+        try {
+            LocalDateTime todayZero = LocalDateTime.now().with(LocalTime.MIN);
+            LocalDateTime yesterdayZero = todayZero.minusDays(1);
+            Date startTime = Date.from(yesterdayZero.atZone(ZoneId.systemDefault()).toInstant());
+            Date endTime = Date.from(todayZero.atZone(ZoneId.systemDefault()).toInstant());
+            log.info("銆恈ollectMchArchive銆戝紑濮嬮噰闆嗕附姘村骞奸棬璇婃帴璇婂畬鎴愯褰�");
+            ichService.collectMchOuthospAndGenerateArchive(
+                    SpecificArchiveConstants.LISHUI_MCH_ORG_ID, startTime, endTime);
+            log.info("銆恈ollectMchArchive銆戜附姘村骞奸棬璇婃帴璇婂畬鎴愯褰曢噰闆嗙粨鏉�");
+        } catch (Exception e) {
+            log.error("銆恈ollectMchArchive銆戜附姘村骞奸棬璇婃帴璇婂畬鎴愯褰曢噰闆嗗紓甯�", e);
+        }
+    }
+
     public void collectHISYesterday() {
         try {
             // 鑾峰彇鏄ㄥぉ0鐐瑰埌浠婂ぉ0鐐圭殑鏃堕棿鑼冨洿
@@ -1735,23 +1854,24 @@
             // 鑾峰彇daysBefore 0鐐瑰埌daysBefore-1 0鐐圭殑鏃堕棿鑼冨洿
             LocalDateTime todayZero = LocalDateTime.now().with(LocalTime.MIN);
             LocalDateTime daysBeforeZeroStart = todayZero.minusDays(daysBefore);
-            LocalDateTime daysBeforeZeroEnd = todayZero.minusDays(daysBefore-1L);
+            LocalDateTime daysBeforeZeroEnd = todayZero.minusDays(daysBefore - 1L);
             DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
             String startTime = daysBeforeZeroStart.format(formatter);
             String endTime = daysBeforeZeroEnd.format(formatter);
             // HIS鏁版嵁閲囬泦
-            log.info("銆恈ollectHISDaysBefore銆慔IS寮�濮嬮噰闆嗘暟鎹�: startTime:{}, endtime:{}",startTime, endTime);
+            log.info("銆恈ollectHISDaysBefore銆慔IS寮�濮嬮噰闆嗘暟鎹�: startTime:{}, endtime:{}", startTime, endTime);
             // 绔嬪嵆杩斿洖锛屽悗鍙板紓姝ユ墽琛�
             CompletableFuture.runAsync(() -> {
                 ichService.syncMedInhosp(startTime, endTime);
             });
-            log.info("銆恈ollectHISDaysBefore銆慔IS缁撴潫閲囬泦鏁版嵁: startTime:{}, endtime:{}",startTime, endTime);
+            log.info("銆恈ollectHISDaysBefore銆慔IS缁撴潫閲囬泦鏁版嵁: startTime:{}, endtime:{}", startTime, endTime);
         } catch (Exception e) {
             log.error("銆恈ollectHISDaysBefore銆慔IS鏁版嵁閲囬泦寮傚父", e);
         }
     }
 
     public Boolean setSuccessPreachForm(ServiceSubtask serviceSubtask, String preachform, String remark, String failSendstate) {
+        log.info("setSuccessPreachForm鐨勫叆鍙備负锛歴erviceSubtask = {}锛�  preachform = {}锛�  remark = {}锛� failSendstate = {}", serviceSubtask, preachform, remark, failSendstate);
         if (preachform.equals("-1")) {
             //璇存槑閮戒笉闇�瑕佹墽琛屼簡
             ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
@@ -1769,7 +1889,7 @@
         serviceSubtaskPreachform.setTaskid(serviceSubtask.getTaskid());
         serviceSubtaskPreachform.setOrgid(serviceSubtask.getOrgid());
         List<ServiceSubtaskPreachform> sspCount = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
-
+        log.info("sspCount鐨勫�间负锛歿}", sspCount);
         serviceSubtaskPreachform.setPreachform(preachform);
         //1:鏈彂閫佺姸鎬�
         serviceSubtaskPreachform.setSendstate("1");
@@ -1779,7 +1899,7 @@
 //        //浜哄伐鐨勬湭鍙戦�佺姸鎬侊紝闇�瑕佹煡2
 //        if (preachform.equals("1") && StringUtils.isNotEmpty(failSendstate) && Long.valueOf(failSendstate) > 2)
 //            serviceSubtaskPreachform.setSendstate("2");
-        log.error("-----serviceSubtaskPreachform鐨勫叆鍙傛槸锛焮}", serviceSubtaskPreachform);
+        log.info("-----serviceSubtaskPreachform鐨勫叆鍙傛槸锛焮}", serviceSubtaskPreachform);
         List<ServiceSubtaskPreachform> serviceSubtaskPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
         if (CollectionUtils.isNotEmpty(serviceSubtaskPreachforms)) {
             ServiceSubtaskPreachform serviceSubtaskPreachform1 = serviceSubtaskPreachforms.get(0);
@@ -1790,10 +1910,9 @@
             }
             serviceSubtaskPreachform1.setRemark(remark);
             serviceSubtaskPreachformMapper.updateServiceSubtaskPreachform(serviceSubtaskPreachform1);
-
+            log.info("---------serviceSubtaskPreachform1鐨勫叆鍙傛槸 :  {}", serviceSubtaskPreachform1);
             //濡傛灉褰撳墠鐨刾reachform宸茬粡鏄渶鍚庝竴涓簡锛岄偅鐩存帴灏唖erviceSubtask鐨剆endstate鐘舵�佹敼鎴�7灏辫浜�(鍏ㄨ秴鏃朵簡)
-            if (serviceSubtaskPreachform1.getSort() == sspCount.size()
-                    && isSubtaskDeadline(serviceSubtask, serviceSubtaskPreachforms)) {
+            if (serviceSubtaskPreachform1.getSort() == sspCount.size() && isSubtaskDeadline(serviceSubtask, serviceSubtaskPreachforms)) {
                 if (failSendstate.equals("4") || failSendstate.equals("5")) {
                     serviceSubtask.setCurrentPreachform(preachform);
                     serviceSubtask.setSendstate(7L);
@@ -1808,7 +1927,7 @@
             log.error("銆愬畾鏃朵换鍔′腑璇ユ偅鑰呮病鏈夋煡璇㈠埌灞炰簬浠栫殑鍙戦�佹柟寮忥紝subid锛歿},prechform:{},orgid:{}銆�", serviceSubtask.getId(), preachform, serviceSubtask.getOrgid());
             return false;
         }
-
+        log.info("鍒拌繖閲屼簡涓嶏紵锛燂紵锛�");
         //灏嗕笅涓�娆$殑闅忚鏃堕棿涓庡綋鍓嶆墽琛屾柟寮忚褰曚竴涓�
         serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime()));
         serviceSubtask.setCurrentPreachform(preachform);
@@ -1821,6 +1940,7 @@
             }
         }
         serviceSubtask.setRemark(StringUtils.isNotEmpty(serviceSubtask.getRemark()) ? serviceSubtask.getRemark() + "," + remark : remark);
+        log.info("serviceSubtask鐨勫叆鍙傛槸锛歿}",serviceSubtask);
         serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
         return true;
     }
@@ -1833,14 +1953,15 @@
      * @return
      */
     private String getObject(ServiceSubtask serviceSubtask, String scriptContent) {
+        //鍐呭涓虹┖鏃剁洿鎺ヨ繑鍥烇紝閬垮厤涓嬮潰鐨剅eplace鍑虹幇绌烘寚閽�
+        if (StringUtils.isEmpty(scriptContent)) {
+            return scriptContent;
+        }
         Map<String, Map<String, String>> param = getParam(serviceSubtask.getTaskid());
         for (Map<String, String> map : param.values()) {
             for (String key : map.keySet()) {
                 scriptContent = scriptContent.replace(key, StringUtils.isNotEmpty(map.get(key)) ? map.get(key) : "");
             }
-        }
-        if (StringUtils.isEmpty(scriptContent)) {
-            return scriptContent;
         }
         scriptContent = scriptContent.replace("${name}", StringUtils.isNotEmpty(serviceSubtask.getSendname()) ? serviceSubtask.getSendname() : "");
         scriptContent = scriptContent.replace("${dzz}", StringUtils.isNotEmpty(serviceSubtask.getAddr()) ? serviceSubtask.getAddr() : "");
@@ -1926,50 +2047,106 @@
 
     /**
      * 闅忚浠诲姟鏄惁瓒呮椂
+     *
      * @param serviceSubtask
      * @param serviceSubtaskPreachforms
      * @return
      */
-    public boolean isSubtaskDeadline(ServiceSubtask serviceSubtask, List<ServiceSubtaskPreachform> serviceSubtaskPreachforms){
+    public boolean isSubtaskDeadline(ServiceSubtask serviceSubtask, List<ServiceSubtaskPreachform> serviceSubtaskPreachforms) {
         if (ObjectUtils.isNotEmpty(serviceSubtask)) {
             //鍙湁鍑洪櫌闅忚鍜屼笓鐥呴殢璁挎湁瓒呮椂
-            if(StringUtils.isNotEmpty(serviceSubtask.getServiceType()) &&
-                    !serviceSubtask.getServiceType().equals("2") && !serviceSubtask.getServiceType().equals("13")){
+            if (StringUtils.isNotEmpty(serviceSubtask.getServiceType()) && !serviceSubtask.getServiceType().equals("2") && !serviceSubtask.getServiceType().equals("13")) {
                 return true;
             }
         }
         if (Objects.isNull(serviceSubtask) || CollectionUtils.isEmpty(serviceSubtaskPreachforms)) {
             return false;
         }
-        // 鍩哄噯鏃跺埢锛氬嚭闄㈡椂闂� + 鍙戦�佹棩锛坰endDay 缂虹渷鎸� 1锛夛紝骞跺厹搴曢伩鍏� NPE/鑴忔暟鎹�
         ServiceTask serviceTask = serviceTaskMapper.selectServiceTaskByTaskid(serviceSubtask.getTaskid());
-        int sendDay = serviceTask != null && serviceTask.getSendDay() != null ? serviceTask.getSendDay().intValue() : 1;
-        Date deadline = DateUtils.addDays(serviceSubtask.getEndtime(), sendDay);
-        int sumCompensateTime = CollectionUtils.isEmpty(serviceSubtaskPreachforms) ? 0 : serviceSubtaskPreachforms.stream()
-                .mapToInt(x -> x.getCompensateTime() == null ? 0 : Integer.parseInt(x.getCompensateTime()))
+        Date deadline;
+        if (serviceTask != null && "5".equals(serviceTask.getAppltype())) {
+            // 浠诲姟缁勶細鍩哄噯 = schedule_benchmark 瑙f瀽鍑虹殑鏃堕棿 + day_offset锛屼笉鍙犲姞 send_day
+            deadline = resolveTaskGroupDeadlineBase(serviceSubtask);
+            if (deadline == null) {
+                log.warn("銆恑sSubtaskDeadline銆憇ubid锛歿} 浠诲姟缁勫熀鍑嗘椂闂翠负绌猴紝鏃犳硶璁$畻瓒呮椂锛屾寜鏈秴鏃跺鐞�", serviceSubtask.getId());
+                return false;
+            }
+        } else {
+            // 闈炰换鍔$粍锛氬熀鍑� = 鍑洪櫌鏃堕棿 + 鍙戦�佹棩锛坰endDay 缂虹渷鎸� 1锛�
+            if (serviceSubtask.getEndtime() == null) {
+                log.warn("銆恑sSubtaskDeadline銆憇ubid锛歿} endtime涓虹┖锛屾棤娉曡绠楄秴鏃讹紝鎸夋湭瓒呮椂澶勭悊", serviceSubtask.getId());
+                return false;
+            }
+            int sendDay = serviceTask != null && serviceTask.getSendDay() != null ? serviceTask.getSendDay().intValue() : 1;
+            deadline = DateUtils.addDays(serviceSubtask.getEndtime(), sendDay);
+        }
+        int sumCompensateTime = serviceSubtaskPreachforms.stream()
+                .mapToInt(x -> NumberUtils.toInt(x.getCompensateTime(), 0))
                 .sum();
         sumCompensateTime = sumCompensateTime + 1;
-        // 鍙ˉ鍋挎渶鍚庝竴姝ヨ嚜韬殑琛ュ伩鏃堕棿锛堝ぉ锛夛紝鑴忓�间竴寰嬫寜 0 鍏滃簳
+        // 琛ュ伩鏃堕棿鑴忓�间竴寰嬫寜 0 鍏滃簳锛屾渶鍚庡啀鍔� 1 澶╁闄�
         deadline = DateUtils.addDays(deadline, sumCompensateTime);
-        // 鍑洪櫌(鍙戦��)鏃堕棿 + 鏈琛ュ伩鏃堕棿 灏忎簬褰撳墠鏃堕棿 -> 瓒呮椂
         return deadline.getTime() < new Date().getTime();
     }
 
     /**
+     * 浠诲姟缁勫熀鍑嗘椂闂达細鎸� schedule_benchmark 瑙f瀽鍚庡姞 day_offset銆�
+     * 0/鍏跺畠-鑷畾涔夋椂闂� 1-鍏ラ櫌 2-鍑洪櫌 3-灏辫瘖 4-鍏ョ粍
+     */
+    private Date resolveTaskGroupDeadlineBase(ServiceSubtask serviceSubtask) {
+        if (serviceSubtask.getScheduleId() == null || serviceSubtask.getScheduleDetailId() == null) {
+            return null;
+        }
+        ServiceTaskSchedule schedule = serviceTaskScheduleMapper.selectServiceTaskScheduleById(serviceSubtask.getScheduleId());
+        ServiceTaskScheduleDetail detail = serviceTaskScheduleDetailMapper.selectServiceTaskScheduleDetailById(serviceSubtask.getScheduleDetailId());
+        if (schedule == null || detail == null || detail.getDayOffset() == null) {
+            return null;
+        }
+        Date base;
+        Integer benchmark = schedule.getScheduleBenchmark() == null ? 0 : schedule.getScheduleBenchmark();
+        switch (benchmark) {
+            case 1:
+                base = serviceSubtask.getStarttime();
+                break;
+            case 2:
+                base = serviceSubtask.getEndtime();
+                break;
+            case 3:
+                base = serviceSubtask.getAdmindate();
+                break;
+            case 4:
+                base = serviceSubtask.getCreateTime();
+                break;
+            default:
+                base = schedule.getScheduleBenchmarkCustomTime();
+                break;
+        }
+        return base == null ? null : DateUtils.addDays(base, detail.getDayOffset());
+    }
+
+    /**
      * 澶勭悊瓒呮椂闅忚浠诲姟锛堥殢璁胯秴鏃� 鈫� 鐢熸垚"鍐嶆闅忚"锛�
+     * <p>
+     * 鎵弿銆屽嚭闄㈡弧 deadlineDay 澶╀粛鏈畬鎴愩�嶇殑棣栨闅忚浠诲姟锛坰endstate=7 + visit_count=1锛夛紝
+     * 鎸夊綋鍓嶄换鍔$殑 nexttaskid 鐢熸垚鍐嶆闅忚浠诲姟锛岀瀹ゅ浐瀹氫负闅忚涓績绉戝銆�
+     * <p>
+     * 娉ㄦ剰锛氭埅姝㈡椂闂村繀椤诲湪寰幆澶栬绠椾竴娆°�傚巻鍙插疄鐜版妸 {@code deadlineDay = -deadlineDay}
+     * 鍐欏湪寰幆浣撳唴锛屾瘡杞彇鍙嶄竴娆★紝瀵艰嚧鍋舵暟杞敤銆屼粖澶� + deadlineDay銆嶅仛鎴鏃堕棿锛�
+     * 鎶婂嚭闄笉婊� 28 澶╃殑瓒呮椂浠诲姟涔熸壂浜嗚繘鏉ャ��
      * <p>
      * 鈿狅笍 2025 淇锛堝紑鍏冲け鏁堬級锛氭湰鏂规硶鍘熶笉鍒や换浣曟ā鍧楀紑鍏� 鈥斺��
      * 鍏虫帀 {@code inhospvisit.enabled} 鐓ф牱寤�"鍐嶆闅忚"瀛愪换鍔°��
      * <p>
      * <b>涓轰粈涔堣繖閲屾槸"鍏ュ彛鍒ゅ紑鍏�"鑰屼笉鏄儚 {@link #dealOutHospInfo()} 閭f牱鍒囧埌闂ㄩ潰</b>锛�
      * 妯″潡渚у彧鎻愪緵浜� {@code InhospVisitApi#buildAgainVisitDraft}锛堢粍瑁呰崏绋匡級锛�
-     * <b>娌℃湁</b>瀹屾暣鐨�"鎵弿瓒呮椂 鈫� 钀藉簱 鈫� 鍥炲啓鍘熶换鍔$姸鎬�"鍏ュ彛锛�
-     * 鑰屾湰鏂规硶鑷繁缁勮骞� insert锛堣涓嬫柟 {@code insertServiceSubtask}锛夈��
-     * 閫犱竴涓ā鍧楀叆鍙e睘浜庢柊澧炶兘鍔涖�佽秴鍑�"鍙В鍐冲紑鍏�"鐨勮寖鍥达紝鎵�浠ュ彇鏈�灏忔敼鍔細鍏ュ彛瀹堝崼銆�
+     * 瓒呮椂鎵弿涓庡洖鍐欏師浠诲姟鐘舵�佺殑鍏ュ彛鐢� service 渚ф壙鎺ワ紙瑙佷笅鏂� {@code addSubTaskAgainByDeadline}锛夈��
      * <p>
      * 鈿狅笍 鍏ㄤ粨鍙湁 {@code ServiceSubtaskController#dealSubtaskDeadline} 涓�涓皟鐢ㄨ�呫��
+     *
+     * @param orgid       鏈烘瀯ID
+     * @param deadlineDay 鍑洪櫌婊″灏戝ぉ绠楄秴鏃讹紙姝f暟锛屽 28锛�
      */
-    public void dealSubtaskDeadline(String orgid, Integer deadlineDay){
+    public void dealSubtaskDeadline(String orgid, Integer deadlineDay) {
         // 鈿狅笍 寮�鍏冲畧鍗細鍏堝垽鍐嶅共娲伙紝涓� dealOutHospInfo / rollTaskGroupCycle 鍚屽彛寰勩��
         // 鍏抽棴鏃剁洿鎺ヨ繑鍥烇紝涓嶆壂鎻忋�佷笉寤�"鍐嶆闅忚"瀛愪换鍔°��
         if (!inhospVisitFacade.isEnabled()) {
@@ -1983,9 +2160,17 @@
         st.setNexttaskflag("1");
         st.setOrgid(orgid);
         List<ServiceTask> serviceTasks = serviceTaskMapper.selectServiceTaskList(st);
+
+        // 鎴鏃堕棿鍙畻涓�娆★細鍑洪櫌鏃堕棿 <= 浠婂ぉ - deadlineDay
+        int days = Math.abs(ObjectUtils.isEmpty(deadlineDay) ? 28 : deadlineDay);
+        Date deadline = DateUtils.addDays(new Date(), -days);
+        log.info("銆恉ealSubtaskDeadline銆戝紑濮嬫壂鎻�, orgid={}, day={}, deadline={}, 浠诲姟鏁�={}",
+                orgid, days, deadline, serviceTasks.size());
+
         for (ServiceTask serviceTask : serviceTasks) {
-            deadlineDay = -deadlineDay;
-            Date deadline = DateUtils.addDays(new Date(), deadlineDay);
+            if (ObjectUtils.isEmpty(serviceTask.getNexttaskid())) {
+                continue;
+            }
             //閫氳繃浠诲姟ID鎷垮埌鎮h�呬俊鎭�,骞朵笖闅忚鏃堕棿寰楁槸浠婂ぉ涔嬪墠鐨�
             ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity();
             serviceSubtaskVO.setOrgid(orgid);
@@ -1998,42 +2183,15 @@
                     = serviceSubtaskMapper.selectServiceSubtaskList(serviceSubtaskVO);
             log.info("銆恉ealSubtaskDeadline銆戣幏鍙栧埌{}涓秴鏃朵换鍔�, taskid={}", serviceSubtaskList.size(), serviceTask.getTaskid());
             for (ServiceSubtask serviceSubtask : serviceSubtaskList) {
-                PatMedInhosp patMedInhospVo = new PatMedInhosp();
-                patMedInhospVo.setOrgid(serviceSubtask.getOrgid());
-                patMedInhospVo.setInhospid(serviceSubtask.getInhospid());
-                patMedInhospVo.setCry(1);
-                List<PatMedInhosp> patMedInhospList = iPatMedInhospService.selectPatMedInhospList(patMedInhospVo);
-                PatMedInhosp patMedInhosp = new PatMedInhosp();
-                if (!patMedInhospList.isEmpty()) {
-                    patMedInhosp = patMedInhospList.get(0);
-                }else {
-                    continue;
-                }
-                if(ObjectUtils.isEmpty(serviceTask.getNexttaskid())){
-                    continue;
-                }
-                ServiceTask nextServiceTask = serviceTaskMapper.selectServiceTaskByTaskid(serviceTask.getNexttaskid());
-                PatArchive patArchive = patArchiveService.selectPatArchiveByPatid(serviceSubtask.getPatid());
-                String config = configService.selectConfigByKey("visit.early.day");
-                Integer type = 1;
-
-                //鏂板鍐嶆闅忚浠诲姟
-                ServiceSubtask serviceSubtaskAgain = iPatMedInhospService.boxedServiceSubtask(nextServiceTask,
-                        patMedInhosp, patArchive, config, type);
-                serviceSubtaskAgain.setId(null);
-                serviceSubtaskAgain.setUpid(serviceSubtask.getId().intValue());
-                serviceSubtaskAgain.setVisitCount(serviceSubtask.getVisitCount() + 1);
-                serviceSubtaskAgain.setSendstate(2L);
-                serviceSubtaskAgain.setCreateTime(new Date());
-                serviceSubtaskAgain.setUpdateTime(new Date());
-                serviceSubtaskAgain.setVisitType(serviceSubtask.getVisitType());
-                serviceSubtaskAgain.setVisitDeptCode(serviceSubtask.getVisitDeptCode());
-                serviceSubtaskAgain.setVisitDeptName(serviceSubtask.getVisitDeptName());
-                int i = serviceSubtaskMapper.insertServiceSubtask(serviceSubtaskAgain);
-                if (i == 1) {
-                    //鍐嶆闅忚浠诲姟鍒涘缓鎴愬姛鍚庯紝鍘熶换鍔℃敼涓哄け璐ョ姸鎬�
-                    serviceSubtask.setSendstate(5L);
-                    serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
+                try {
+                    // 鐢熸垚閫昏緫缁熶竴鏀跺彛鍒� service锛氶攣 + 骞傜瓑 + 浜嬪姟 + 鍙戦�佹柟寮忔槑缁嗗垵濮嬪寲
+                    String result = iServiceSubtaskService.addSubTaskAgainByDeadline(serviceSubtask);
+                    log.info("銆恉ealSubtaskDeadline銆戠敓鎴愬啀娆¢殢璁�, subId={}, taskid={}, 缁撴灉={}",
+                            serviceSubtask.getId(), serviceTask.getTaskid(), result);
+                } catch (Exception e) {
+                    // 鍗曟潯澶辫触涓嶅奖鍝嶅叾浠栨偅鑰�
+                    log.error("銆恉ealSubtaskDeadline銆戠敓鎴愬啀娆¢殢璁垮け璐�, subId=" + serviceSubtask.getId()
+                            + ", taskid=" + serviceTask.getTaskid(), e);
                 }
             }
         }

--
Gitblit v1.9.3