From 72337c4a38bc8f5dbadbb492e2f0548521842798 Mon Sep 17 00:00:00 2001
From: 陈昶聿 <chychen@nbjetron.com>
Date: 星期四, 22 十月 2026 16:20:12 +0800
Subject: [PATCH] 【丽水】1、出院未到28天超时,也到了随访中心 2、出院28天超时任务,到随访中心的,会一次性生成4条任务

---
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java |  500 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 433 insertions(+), 67 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 3af68ec..cfe92f6 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
@@ -6,21 +6,25 @@
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.Gson;
+import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.entity.SysDept;
+import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.core.service.IDingTalkService;
 import com.ruoyi.common.dx.MessageSend;
 import com.ruoyi.common.enums.MsgLSEnum;
 import com.ruoyi.common.enums.ServiceFromEnum;
 import com.ruoyi.common.enums.WxGZHEnum;
 import com.ruoyi.common.utils.*;
 import com.ruoyi.common.utils.http.HttpUtils;
-import com.ruoyi.common.utils.sms.smsUtils;
+import com.ruoyi.common.utils.sms.SmsUtils;
 import com.ruoyi.quartz.service.ICollectHISService;
 import com.ruoyi.quartz.util.CreateDataTable;
 import com.ruoyi.system.domain.SysConfig;
 import com.ruoyi.system.mapper.SysConfigMapper;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.service.ISysDeptService;
+import com.ruoyi.system.service.ISysUserService;
 import com.smartor.common.LSHospTokenUtil;
 import com.smartor.common.MtSubmitSmUtil;
 import com.smartor.common.QwenLLMUtil;
@@ -48,6 +52,7 @@
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
@@ -103,6 +108,12 @@
     @Autowired
     private ISysConfigService configService;
 
+    @Autowired
+    private IDingTalkService dingTalkService;
+
+    @Autowired
+    private ISysUserService userService;
+
 
     @Value("${localIP}")
     private String localIP;
@@ -150,6 +161,9 @@
     IServiceSubtaskDetailTraceService serviceSubtaskDetailTraceService;
 
     @Autowired
+    IPatMedOuthospService patMedOuthospService;
+
+    @Autowired
     ISvyTaskTemplateService svyTaskTemplateService;
 
     @Autowired
@@ -181,6 +195,21 @@
     private String active;
     @Autowired
     private SysConfigMapper sysConfigMapper;
+
+    @Autowired
+    private IServiceTaskScheduleService serviceTaskScheduleService;
+
+    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) {
+        System.out.println(StringUtils.format("鎵ц澶氬弬鏂规硶锛� 瀛楃涓茬被鍨媨}锛屽竷灏旂被鍨媨}锛岄暱鏁村瀷{}锛屾诞鐐瑰瀷{}锛屾暣褰}", s, b, l, d, i));
+    }
+
+    public void ryParams(String params) {
+        System.out.println("鎵ц鏈夊弬鏂规硶锛�" + params);
+    }
+
+    public void ryNoParams() {
+        System.out.println("鎵ц鏃犲弬鏂规硶");
+    }
 
     public void importData() {
         String filePath = "C:\\Users\\86176\\Desktop\\鏂板缓鏂囨湰鏂囨。 4.txt"; // 鏇挎崲涓轰綘鐨勬枃浠惰矾寰�
@@ -250,6 +279,80 @@
         }
     }
 
+    /**
+     * 瀹氭椂鍙戦�佸紓甯镐俊鎭�-鏅畞
+     */
+    public void sendExceptInfo() throws Exception {
+        //1.鑾峰彇鍙戦�佷汉宸ュ彿
+        ServiceSubtaskDetailTraceVO subtaskDetailTraceVO = new ServiceSubtaskDetailTraceVO();
+        subtaskDetailTraceVO.setHandleFlag("0");
+        List<ServiceSubtaskDetailTrace> serviceSubtaskDetailTraces =
+                serviceSubtaskDetailTraceService.selectServiceSubtaskDetailTtraceList(subtaskDetailTraceVO);
+        // 鑾峰彇鈥滃紓甯稿唴瀹规彁閱�"
+        SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique("send.except.content");
+        String exceptContent = sysConfig.getConfigValue();
+
+        // 鑾峰彇鈥滃唴瀹规彁閱掓祴璇曚汉宸ュ彿鈥�
+        SysConfig testPersonConfig = sysConfigMapper.checkConfigKeyUnique("send.test.person");
+        String testPerson = ObjectUtils.isNotEmpty(testPersonConfig) ? testPersonConfig.getConfigValue() : "";
+        if(CollectionUtils.isNotEmpty(serviceSubtaskDetailTraces)){
+            for (ServiceSubtaskDetailTrace serviceSubtaskDetailTrace : serviceSubtaskDetailTraces) {
+                List<String> dutyDeptPersonCodeList = new ArrayList<>();
+                        // 鎶� dutyDeptPersonCode 鏁寸悊鍒� list 涓紙濡傛灉澶氫釜浜虹敤閫楀彿鍒嗗壊锛屽垯灞曞紑骞跺幓閲嶏級
+                String dutyDeptPersonCodeStr = serviceSubtaskDetailTrace.getDutyDeptPersonCode();
+                if(StringUtils.isNotEmpty(dutyDeptPersonCodeStr)){
+                    String[] dutyDeptPersonCodeSplit = dutyDeptPersonCodeStr.split(",");
+                    if (CollectionUtils.isEmpty(dutyDeptPersonCodeList)) {
+                        dutyDeptPersonCodeList = new ArrayList<>(Arrays.asList(dutyDeptPersonCodeSplit));
+                    } else {
+                        dutyDeptPersonCodeList.addAll(Arrays.asList(dutyDeptPersonCodeSplit));
+                    }
+
+                }
+
+                if (StringUtils.isNotBlank(testPerson)) {
+                    String[] split = testPerson.split(",");
+                    if (CollectionUtils.isEmpty(dutyDeptPersonCodeList)) {
+                        dutyDeptPersonCodeList = new ArrayList<>(Arrays.asList(split));
+                    } else {
+                        dutyDeptPersonCodeList.addAll(Arrays.asList(split));
+                    }
+                }
+
+                if (CollectionUtils.isNotEmpty(dutyDeptPersonCodeList)) {
+                    for (String dutyDeptPersonCode : dutyDeptPersonCodeList) {
+                        log.info("銆恠endExceptInfo銆戝彂閫佷汉宸ュ彿锛歿}", dutyDeptPersonCode);
+                        SysUser sysUser = new SysUser();
+                        SysUser sysUserVo = new SysUser();
+                        sysUserVo.setUserName(dutyDeptPersonCode);
+                        sysUserVo.setOrgid(serviceSubtaskDetailTrace.getOrgid());
+                        List<SysUser> users = userService.getUserList(sysUserVo);
+                        String phoneNumber = "";
+                        if(ObjectUtils.isNotEmpty(users)){
+                            sysUser = users.get(0);
+                            phoneNumber = sysUser.getPhonenumber();
+                        }else {
+                            continue;
+                        }
+
+                        if(StringUtils.isEmpty(phoneNumber)){
+                            continue;
+                        }
+                        String dutyDeptPerson = dingTalkService.getDingTalkUserByMobile(phoneNumber);
+                        if(StringUtils.isNotBlank(dutyDeptPerson)){
+                            String context = TemplateUtils.render(exceptContent, serviceSubtaskDetailTrace);
+                            dingTalkService.sendDingTalkText(context, dutyDeptPerson);
+                            //鏇存柊鐘舵��
+                            serviceSubtaskDetailTrace.setHandleFlag("1");
+                            serviceSubtaskDetailTrace.setUpdateTime(new Date());
+                            serviceSubtaskDetailTraceService.updateServiceSubtaskDetailTtrace(serviceSubtaskDetailTrace);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
 
     /**
      * 瀹氭椂澶勭悊澶栭摼鐨勬暟鎹�
@@ -267,6 +370,17 @@
         LocalDateTime tomorrowEnd = tomorrowStart.plusDays(1).minusSeconds(1);     // 鏄庡ぉ 23:59:59
         ixhGatherPatArchiveService.getAppointRecordInfo("2", tomorrowStart, tomorrowEnd);
     }
+
+    /**
+     * 姣忔湀15鍙峰拰鏈堝簳锛屾煡璇㈠苟澶勭悊 HIS 鏁版嵁锛堝悓寰凤紝鍗楀崕锛�
+     */
+    public void dealHisDataHalfMonth() {
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        String formattedNow = now.format(formatter);
+        dealHisData(formattedNow);
+    }
+
 
     /**
      * HIS鏁版嵁閲囬泦
@@ -364,7 +478,7 @@
                     iIcd10Service.queryAddIcd10();
                 }
 
-                // nhfy/sltd鍥炴函30澶╁垎娈甸噰闆嗗垽鏂紙姣忔鏈�澶�7澶╋級
+                // nhfy/sltd鍥炴函30澶╁垎娈甸噰闆嗗垽鏂紙姣忔鏈�澶�4澶╋級
                 boolean isBackfill = (active.trim().equals("nhfy") || active.trim().equals("sltd")) && StringUtils.isNotBlank(todayZeroStr);
                 if (isBackfill) {
                     DateTimeFormatter dateFmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
@@ -372,7 +486,7 @@
                     LocalDate segEndDate = todayZero.toLocalDate();
                     int segCount = 0;
                     while (!segStart.isAfter(segEndDate)) {
-                        LocalDate segEnd = segStart.plusDays(6);
+                        LocalDate segEnd = segStart.plusDays(3);
                         if (segEnd.isAfter(segEndDate)) {
                             segEnd = segEndDate;
                         }
@@ -405,7 +519,7 @@
                         list.add("FH0109.23");
                         list.add("FH0109.53");
                         serviceSLTDInhospReqVO.setStatusList(list);
-                        log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滈鍏ラ櫌鈥濋噰闆嗘暟鎹叆鍙傦細{}", serviceSLTDInhospReqVO);
+//                        log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滈鍏ラ櫌鈥濋噰闆嗘暟鎹叆鍙傦細{}", serviceSLTDInhospReqVO);
                         serviceSLTDHealthcareRecordService.queryHealthcareRecordList(serviceSLTDInhospReqVO);
                         log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滈鍏ラ櫌鈥濈祼鏉熼噰闆嗘暟鎹紝闄㈠尯锛歿}", cid);
 
@@ -423,7 +537,7 @@
                         List<String> listStr = new ArrayList<>();
                         listStr.add("FH0109.24");
                         serviceSLTDInhospReqVO.setStatusList(listStr);
-                        log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滃叆闄⑩�濋噰闆嗘暟鎹叆鍙傦細{}", serviceSLTDInhospReqVO);
+//                        log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滃叆闄⑩�濋噰闆嗘暟鎹叆鍙傦細{}", serviceSLTDInhospReqVO);
                         serviceSLTDHealthcareRecordService.queryHealthcareRecordList(serviceSLTDInhospReqVO);
                         log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滃叆闄⑩�濈祼鏉熼噰闆嗘暟鎹紝闄㈠尯锛歿}", cid);
 
@@ -446,7 +560,7 @@
                         //棰勫嚭闄�
                         list2.add("FH0109.25");
                         serviceSLTDInhospReqVO.setStatusList(list2);
-                        log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滃嚭闄⑩�濋噰闆嗘暟鎹叆鍙傦細{}", serviceSLTDInhospReqVO);
+//                        log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滃嚭闄⑩�濋噰闆嗘暟鎹叆鍙傦細{}", serviceSLTDInhospReqVO);
                         serviceSLTDHealthcareRecordService.queryHealthcareRecordList(serviceSLTDInhospReqVO);
                         log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滃嚭闄⑩�濇潫閲囬泦鏁版嵁锛岄櫌鍖猴細{}", cid);
                     }
@@ -467,7 +581,7 @@
      * @param endDateStr   鏃ユ湡缁撴潫 yyyy-MM-dd
      */
     private void collectSegmentData(Long cid, String startDateStr, String endDateStr) {
-        // 棰勫叆闄�
+//        // 棰勫叆闄�
         log.info("銆恉ealHisData銆戦鍏ラ櫌寮�濮嬮噰闆嗘暟鎹紝闄㈠尯锛歿}锛屾椂闂存锛歿} ~ {}", cid, startDateStr, endDateStr);
         ServiceSLTDInhospReqVO reqVO = new ServiceSLTDInhospReqVO();
         reqVO.setOrgId("20001001");
@@ -617,13 +731,31 @@
         ServiceSLTDInhospReqVO serviceSLTDInhospReqVO = new ServiceSLTDInhospReqVO();
         serviceSLTDInhospReqVO.setOrgId("20001001");
         Long outpPage = 1L;
+        int totalCount = 0;  // 缁熻鎬诲叡閲囬泦鐨勮嵂鍝佹暟閲�
+
         while (true) {
             serviceSLTDInhospReqVO.setCurrent(outpPage);
             serviceSLTDInhospReqVO.setSize(OUTP_PAGE_SIZE);
-            log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滆嵂鍝佹暟鎹�濋噰闆嗙{}椤垫暟鎹�", outpPage);
-            Boolean b = serviceSLTDHealthcareRecordService.queryMedicationItemList(serviceSLTDInhospReqVO);
-            log.info("銆恉ealHisData銆戠渷绔嬪悓寰封�滆嵂鍝佹暟鎹�濋噰闆嗙粨鏋滐細{}", b);
-            outpPage++;
+            log.info("銆恉ealHisData銆戠渷绔嬪悓寰穃"鑽搧鏁版嵁\"閲囬泦绗瑊}椤垫暟鎹�", outpPage);
+
+            try {
+                Integer fetchedCount = serviceSLTDHealthcareRecordService.queryMedicationItemList(serviceSLTDInhospReqVO);
+                log.info("銆恉ealHisData銆戠渷绔嬪悓寰穃"鑽搧鏁版嵁\"绗瑊}椤甸噰闆嗗埌{}鏉¤褰�", outpPage, fetchedCount);
+
+                totalCount += fetchedCount != null ? fetchedCount : 0;
+
+                // 濡傛灉杩斿洖鐨勬暟鎹噺灏忎簬 pageSize锛岃鏄庡凡缁忔槸鏈�鍚庝竴椤典簡锛岄��鍑哄惊鐜�
+                if (fetchedCount == null || fetchedCount < OUTP_PAGE_SIZE) {
+                    log.info("銆恉ealHisData銆戠渷绔嬪悓寰穃"鑽搧鏁版嵁\"閲囬泦瀹屾垚锛屾�婚〉鏁�:{}, 鎬昏{}鏉¤褰�", outpPage, totalCount);
+                    break;
+                }
+
+                outpPage++;
+            } catch (Exception e) {
+                log.error("銆恉ealHisData銆戠渷绔嬪悓寰穃"鑽搧鏁版嵁\"绗瑊}椤甸噰闆嗗け璐�", outpPage, e);
+                // 鍑洪敊鏃朵篃鍙互閫夋嫨閫�鍑烘垨缁х画锛岃繖閲岄�夋嫨閫�鍑洪伩鍏嶆棤闄愰噸璇�
+                break;
+            }
         }
     }
 
@@ -668,7 +800,7 @@
     public void dealHisData2() {
         //灏嗘偅鑰呬俊鎭�佸嚭鍏ラ櫌鏁版嵁鍏ㄩ儴閲囬泦
         // 鎸囧畾鐨勫紑濮嬫棩鏈�
-        LocalDate endDate = LocalDate.of(2025, 3, 3);
+        LocalDate endDate = LocalDate.of(2026, 7, 6);
         // 褰撳墠鏃ユ湡
         LocalDate currentDate = LocalDate.now();
         // 瀹氫箟鏃ユ湡鏍煎紡
@@ -699,17 +831,17 @@
     }
 
     /**
-     * 澶勭悊鎮h�呬俊鎭紝杩涘叆瀛愪换鍔¤〃
+     * 澶勭悊鎮h�呬俊鎭紝杩涘叆瀛愪换鍔¤〃(浠诲姟缁�)
      */
-    public void dealOutHospInfoByDimension() {
+    public void dealOutHospInfoBySchedule() {
         String config = configService.selectConfigByKey("visit.early.day");
         if (port.equals("8095")) {
             //鍑洪櫌琛�
-            iPatMedInhospService.dealOutHospInfoByDimension(config);
+            iPatMedInhospService.dealOutHospInfoBySchedule(config);
             //闂ㄨ瘖琛�(鏂板崕鐨勬殏鏃朵笉鍋氶棬璇婇殢璁�)
-            if (!active.equals("xh")) {
-                //iPatMedOuthospService.dealOutpatientInfo();
-            }
+//            if (!active.equals("xh")) {
+//                //iPatMedOuthospService.dealOutpatientInfo();
+//            }
         }
     }
 
@@ -780,12 +912,24 @@
      * 澶勭悊琛ュ伩浠诲姟
      */
     public void compensateTask() {
-        //鑾峰彇鍒皊endstate=3 骞朵笖 visit_time涓哄皬浜庣瓑浜庝粖澶╃殑subtask
+        //鑾峰彇鍒皊endstate=3銆�1 骞朵笖 visit_time涓哄皬浜庣瓑浜庝粖澶╃殑subtask
+        List<Long> list = Arrays.asList(3L, 1L);
         ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity();
-        serviceSubtaskVO.setSendstate(3L);
-        serviceSubtaskVO.setVisitTime(new Date());
-        List<ServiceSubtask> serviceSubtaskList = serviceSubtaskMapper.getCompensateServiceSubtaskList(serviceSubtaskVO);
+        List<ServiceSubtask> serviceSubtaskList = new ArrayList<>();
+        for (Long sendstate : list) {
+            serviceSubtaskVO.setSendstate(sendstate);
+            serviceSubtaskVO.setVisitTime(new Date());
+            List<ServiceSubtask> compensateServiceSubtaskList = serviceSubtaskMapper.getCompensateServiceSubtaskList(serviceSubtaskVO);
+            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());
@@ -806,7 +950,9 @@
 
                 //2鍒ゆ柇涓�涓嬶紝褰撳墠鐨剆ort鏄笉鏄瓑浜庨渶瑕佹墽琛岀殑鎬讳釜鏁帮紝濡傛灉绛変簬鐨勮瘽锛岃鏄庢槸鏈�鍚庝竴涓紝鐩存帴灏唖ervuce_subtask鐨勭姸鎬佹敼鎴�5锛屾墽琛屽け璐ュ氨琛屼簡
                 Long cs = currentSort.get();
-                if (cs.equals(serviceSubtaskPreachforms.size())) {
+
+                if (cs.equals(serviceSubtaskPreachforms.size())
+                        && isSubtaskDeadline(serviceSubtask, serviceSubtaskPreachforms)) {
                     serviceSubtask.setSendstate(7L);
                     serviceSubtask.setRemark("澶勭悊琛ュ伩浠诲姟,褰撳墠澶勭悊鏈�鍚庤ˉ鍋匡紝鍏ㄩ儴鎵ц澶辫触锛堣秴鏃讹級");
 
@@ -854,6 +1000,24 @@
         LocalDate today = LocalDate.now();
         // 濡傛灉鏃ユ湡鏃╀簬鎴栫瓑浜庝粖澶╋紝杩斿洖 true
         return !localDate.isAfter(today);
+    }
+
+    /**
+     * 鎸夋満鏋勬煡璇㈤厤缃�硷紙鍚屼竴 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;
     }
 
     /**
@@ -971,18 +1135,17 @@
                     serviceOutPath.setCreateTime(new Date());
                     serviceOutPath.setOrgid(serviceSubtask.getOrgid());
                     iServiceOutPathService.insertServiceOutPath(serviceOutPath);
+                    String url = "";
                     String format = String.format("%03X", serviceOutPath.getId());
-                    serviceOutPath.setRadix(format);
-                    serviceOutPath.setUpdateTime(new Date());
-                    iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                     //鍏堝垽鏂竴涓嬪彂鐨勬槸涓嶆槸瀹f暀
                     if (!"3".equals(serviceSubtask.getType())) {
                         sendMagParam.setPhone(serviceSubtask.getPhone());
-
-                        sendMagParam.setUrl(StringUtils.isNotEmpty(req_path) ? localIP + ":" + req_path + "/wt?p=" + format : localIP + "/wt?p=" + format);
+                        url = StringUtils.isNotEmpty(req_path) ? localIP + ":" + req_path + "/wt?p=" + format : localIP + "/wt?p=" + format;
+                        sendMagParam.setUrl(url);
                         //濡傛灉type鏄闊抽殢璁跨殑璇濓紙璇存槑琛ュ伩鍙戦�佹柟寮忎腑鏈夌數璇濋殢璁跨殑鏂瑰紡锛岃繖閲岀殑澶栭摼灏卞湴鍧�鍙兘鐢�/sf锛�
                         if (serviceSubtask.getType().equals("1"))
-                            sendMagParam.setUrl(StringUtils.isNotEmpty(req_path) ? localIP + ":" + req_path + "/sf?p=" + format : localIP + "/sf?p=" + format);
+                            url = StringUtils.isNotEmpty(req_path) ? localIP + ":" + req_path + "/sf?p=" + format : localIP + "/sf?p=" + format;
+                            sendMagParam.setUrl(url);
 
 //                        SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique("wj.sms.template");
                         SysConfig sysConfig = new SysConfig();
@@ -993,7 +1156,7 @@
                         } else {
                             sysConfig = sysConfigMapper.checkConfigKeyUnique("wj.sms.template");
                         }
-                        if (!Objects.isNull(sysConfig)) {
+                        if (!Objects.isNull(sysConfig) && StringUtils.isNotEmpty(sysConfig.getConfigValue())) {
                             String smsContemt = sysConfig.getConfigValue();
 //                            sendMagParam.setContent("鎮ㄥソ锛岄個璇锋偍濉啓鍑洪櫌璋冩煡琛紝璇风偣鍑�" + sendMagParam.getUrl() + "濉啓銆傛劅璋㈡偍閰嶅悎锛�");
                             sendMagParam.setContent(smsContemt.replace("${wjurl}", sendMagParam.getUrl()));
@@ -1002,10 +1165,12 @@
                         HeLibrary heLibrary = heLibraryMapper.selectHeLibraryById(serviceSubtask.getLibtemplateid());
                         if (heLibrary.getHetype().equals("1")) {
                             sendMagParam.setPhone(serviceSubtask.getPhone());
-                            sendMagParam.setUrl(StringUtils.isNotEmpty(req_path) ? localIP + ":" + req_path + "/xj?p=" + format : localIP + "/xj?p=" + format);
+                            url = StringUtils.isNotEmpty(req_path) ? localIP + ":" + req_path + "/xj?p=" + format : localIP + "/xj?p=" + format;
+
+                            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()));
@@ -1020,6 +1185,18 @@
                         }
 
                     }
+
+                    //鍐呭涓虹┖璇存槑鐭俊妯℃澘鏈厤缃垨瀹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);
+                    iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                     String isSuccess = null;
                     log.info("active鐨勫�间负锛歿}", active);
                     if (active.equals("xh")) {
@@ -1051,33 +1228,48 @@
 //                        String url = configService.selectConfigByKey("token.360", serviceSubtask.getOrgid());
 //                        //涓芥按鐨勭煭淇″彂閫佹柟寮�
 //                        Map<String, String> map = MsgLSEnum.getAddressByCode(serviceSubtask.getOrgid());
-                        SysConfig config = new SysConfig();
-                        config.setConfigKey("ls.msg.info");
-                        config.setOrgid(serviceSubtask.getOrgid());
-                        List<SysConfig> sysConfigs = configService.selectConfigList(config);
-                        Map<String, String> msgInfo = new HashMap<>();
-                        if (CollectionUtils.isNotEmpty(sysConfigs)) {
-                            String configValue = sysConfigs.get(0).getConfigValue();
+                        if ("47226079133110211G1001".equals(serviceSubtask.getOrgid())) {
+                            // 濡囧辜涓浗绉诲姩浜慚AS锛屼笉渚濊禆 ls.msg.info 涓� token
+                            SmsUtils.YunMasConfig yunMasConfig = SmsUtils.YunMasConfig.of(getConfigValue("ls.msg.yunmas", serviceSubtask.getOrgid()));
+                            SmsUtils.SmsResult smsResult = SmsUtils.sendYunMasSms(yunMasConfig, sendMagParam.getPhone(), sendMagParam.getContent());
+                            log.info("銆恠fHandlle銆戜簯MAS鐭俊鍙戦�佺粨鏋滐細ok={}锛宺spcod={}锛宮sgGroup={}锛宮essage={}",
+                                    smsResult.isOk(), smsResult.getRspcod(), smsResult.getMsgGroup(), smsResult.getMessage());
+                            if (smsResult.isOk()) {
+                                isSuccess = "true";
+                            } else {
+                                log.error("銆恠fHandlle銆戜簯MAS鐭俊鍙戦�佸け璐ワ紝subid锛歿}锛屾墜鏈哄彿锛歿}锛屽師鍥狅細{}",
+                                        serviceSubtask.getId(), sendMagParam.getPhone(), smsResult.getMessage());
+                            }
+                        } else {
+                            SysConfig config = new SysConfig();
+                            config.setConfigKey("ls.msg.info");
+                            config.setOrgid(serviceSubtask.getOrgid());
+                            List<SysConfig> sysConfigs = configService.selectConfigList(config);
+                            Map<String, String> msgInfo = new HashMap<>();
+                            if (CollectionUtils.isNotEmpty(sysConfigs)) {
+                                String configValue = sysConfigs.get(0).getConfigValue();
+                                ObjectMapper objectMapper = new ObjectMapper();
+                                if (StringUtils.isNotEmpty(configValue)) {
+                                    msgInfo = objectMapper.readValue(configValue, Map.class);
+                                }
+                            }
+                            log.info("-----------map鐨勫�间负锛歿}", msgInfo);
+                            if (ObjectUtils.isEmpty(msgInfo) || StringUtils.isEmpty(msgInfo.get("address"))) {
+                                setSuccessPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�,璇ユ満鏋勬病鏈夐厤缃煭淇″湴鍧�, 鏃堕棿:" + now, "5");
+                                return;
+                            }
+                            String token = LSHospTokenUtil.getToken(serviceSubtask.getOrgid(), msgInfo.get("tokenUrl"));
+                            log.info("銆恠fHandlle銆戜附姘寸煭淇″彂閫侊紝鍦板潃锛歿}锛屽弬鏁帮細{}锛屾満鏋処D锛歿}", msgInfo.get("address"), sendMagParam, serviceSubtask.getOrgid());
+                            String dxCode = getDXCode(msgInfo.get("address"), sendMagParam.getPhone(), sendMagParam.getContent(), msgInfo.get("sendPersonId"), msgInfo.get("sendPersonName"), MsgLSEnum.getHeaderByCode(msgInfo), token);
+                            log.info("銆恠fHandlle銆戜附姘寸煭淇″彂閫佺粨鏋滐細{}", dxCode);
                             ObjectMapper objectMapper = new ObjectMapper();
-                            if (StringUtils.isNotEmpty(configValue)) {
-                                msgInfo = objectMapper.readValue(configValue, Map.class);
+                            Map<String, Object> textParam = objectMapper.readValue(dxCode, Map.class);
+                            String code = textParam.get("Code").toString();
+                            if (code.equals("0")) {
+                                isSuccess = "true";
                             }
                         }
-                        log.info("-----------map鐨勫�间负锛歿}", msgInfo);
-                        String token = LSHospTokenUtil.getToken(serviceSubtask.getOrgid(), msgInfo.get("tokenUrl"));
-                        if (ObjectUtils.isNotEmpty(msgInfo) && StringUtils.isEmpty(msgInfo.get("address"))) {
-                            setSuccessPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�,璇ユ満鏋勬病鏈夐厤缃煭淇″湴鍧�, 鏃堕棿:" + now, "5");
-                            return;
-                        }
-                        log.info("銆恠fHandlle銆戜附姘寸煭淇″彂閫侊紝鍦板潃锛歿}锛屽弬鏁帮細{}锛屾満鏋処D锛歿}", msgInfo.get("address"), sendMagParam, serviceSubtask.getOrgid());
-                        String dxCode = getDXCode(msgInfo.get("address"), sendMagParam.getPhone(), sendMagParam.getContent(), msgInfo.get("sendPersonId"), msgInfo.get("sendPersonName"), MsgLSEnum.getHeaderByCode(msgInfo), token);
-                        log.info("銆恠fHandlle銆戜附姘寸煭淇″彂閫佺粨鏋滐細{}", dxCode);
-                        ObjectMapper objectMapper = new ObjectMapper();
-                        Map<String, Object> textParam = objectMapper.readValue(dxCode, Map.class);
-                        String code = textParam.get("Code").toString();
-                        if (code.equals("0")) {
-                            isSuccess = "true";
-                        }
+
                     } else if (active.equals("sltd") || active.equals("nhfy")) {
                         log.info("sltd杩涙潵浜嗗悧锛焮}   ,---sendMagParam.getContent()鐨勫弬鏁颁负锛歿}", active, sendMagParam.getContent());
                         if (active.equals("sltd")) {
@@ -1125,13 +1317,13 @@
                         String campusid = ObjectUtils.isNotEmpty(sysDept) ? sysDept.getCampusid() : "2";
                         //婀栨花鍗曠嫭鍙戦�佹柟寮�
                         if ("1".equals(campusid)) {
-                            String result = smsUtils.sendSms1(xhsmsPath, xhsmsAccount, xhsmsPwd, sendMagParam.getPhone(), content);
+                            String result = SmsUtils.sendSms1(xhsmsPath, xhsmsAccount, xhsmsPwd, sendMagParam.getPhone(), content);
                             //杩欓噷闇�瑕佹牴鎹畆esult杩斿洖鐨勫�煎幓鍒ゆ柇锛屾槸鍚︽垚鍔燂紝鐒跺悗灏嗗�艰祴鍊肩粰isSuccess
                             if (StringUtils.isNotEmpty(result) && result.contains("澶勭悊鎴愬姛")) {
                                 isSuccess = "true";
                             }
                         } else {
-                            String result = smsUtils.sendSms(xhsmsPath, xhsmsAccount, xhsmsPwd, sendMagParam.getPhone(), content);
+                            String result = SmsUtils.sendSms(xhsmsPath, xhsmsAccount, xhsmsPwd, sendMagParam.getPhone(), content);
                             //杩欓噷闇�瑕佹牴鎹畆esult杩斿洖鐨勫�煎幓鍒ゆ柇锛屾槸鍚︽垚鍔燂紝鐒跺悗灏嗗�艰祴鍊肩粰isSuccess
                             if (StringUtils.isNotEmpty(result) && result.contains("澶勭悊鎴愬姛")) {
                                 isSuccess = "true";
@@ -1193,6 +1385,7 @@
                     String format = String.format("%03X", serviceOutPath.getId());
                     serviceOutPath.setRadix(format);
                     serviceOutPath.setUpdateTime(new Date());
+                    serviceOutPath.setUrl(url);
                     iServiceOutPathService.updateServiceOutPath(serviceOutPath);
 
                     //鑾峰彇寰俊鍏紬鍙疯姹備俊鎭牴鎹満鏋処D
@@ -1212,7 +1405,7 @@
                     //甯備竴鍖婚櫌
                     if (active.equals("hzszlyy")) {
                         //澶勭悊涓枃涔辩爜闂
-                        wxCode = smsUtils.sendChat(url, patArchive.getTelcode(), serviceSubtask.getSfzh());
+                        wxCode = SmsUtils.sendChat(url, patArchive.getTelcode(), serviceSubtask.getSfzh());
                     } else {
                         wxCode = getWXCode(serviceSubtask.getSfzh(), url, serviceSubtask.getTaskName(), serviceSubtask.getTaskDesc(), patArchive.getTelcode(), serviceSubtask.getSendname(), patArchive.getPatidHis(), wxqqxx);
                     }
@@ -1321,15 +1514,15 @@
                 serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                 return "-1";
             }
-
             // 褰搒ort绛変簬鍒楄〃size鏃讹紝骞朵笖鎵�鏈塻endstate閮戒笉绛変簬9锛屽垯杩斿洖-1
-            if (currentSort.get().equals((long) serviceSubtaskPreachforms.size())) {
+            if (currentSort.get().equals((long) serviceSubtaskPreachforms.size())
+                    && isSubtaskDeadline(serviceSubtask, serviceSubtaskPreachforms)) {
                 if (allSendStateNot1AndNot9) {
                     //璇存槑鍏ㄥ彂閫佸け璐ヤ簡
                     serviceSubtask.setSendstate(7L);
                     serviceSubtask.setFinishtime(null);
                     log.error("getSendPreachform鏂规硶 妫�鏌ユ槸鍚︽墍鏈塻endstate涓嶇瓑浜�9, 鍏ㄥけ璐ヤ簡");
-                    serviceSubtask.setRemark(StringUtils.isNotEmpty(serviceSubtask.getRemark()) ? serviceSubtask.getRemark() + "," + "鎵�鏈夊彂閫佹柟寮忓潎鏈幏鍙栫粨鏋滐紝浠诲姟澶辫触锛堣秴鏃讹級" : "鎵�鏈夊彂閫佹柟寮忓潎鏈幏鍙栫粨鏋滐紝浠诲姟澶辫触锛堣秴鏃讹級");
+                    serviceSubtask.setRemark(StringUtils.isNotEmpty(serviceSubtask.getRemark()) ? serviceSubtask.getRemark() + "," + "鎵�鏈夋墽琛屾柟寮忓潎鏈幏鍙栫粨鏋滐紝浠诲姟澶辫触锛堣秴鏃讹級" : "鎵�鏈夋墽琛屾柟寮忓潎鏈幏鍙栫粨鏋滐紝浠诲姟澶辫触锛堣秴鏃讹級");
                     serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                     //淇敼鍙戦�佺姸鎬�
                     setFail(serviceSubtaskPreachforms, serviceSubtask);
@@ -1479,6 +1672,47 @@
         }
     }
 
+    public void collectHISYesterday() {
+        try {
+            // 鑾峰彇鏄ㄥぉ0鐐瑰埌浠婂ぉ0鐐圭殑鏃堕棿鑼冨洿
+            LocalDateTime todayZero = LocalDateTime.now().with(LocalTime.MIN);
+            LocalDateTime yesterdayZero = todayZero.minusDays(1);
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+            String startTime = yesterdayZero.format(formatter);
+            String endTime = todayZero.format(formatter);
+            // HIS鏁版嵁閲囬泦
+            log.info("銆恈ollectHISYesterday銆慔IS寮�濮嬮噰闆嗘暟鎹�");
+            // 绔嬪嵆杩斿洖锛屽悗鍙板紓姝ユ墽琛�
+            CompletableFuture.runAsync(() -> {
+                ichService.syncMedInhosp(startTime, endTime);
+            });
+            log.info("銆恈ollectHISYesterday銆慔IS缁撴潫閲囬泦鏁版嵁");
+        } catch (Exception e) {
+            log.error("銆恈ollectHISYesterday銆慔IS鏁版嵁閲囬泦寮傚父", e);
+        }
+    }
+
+    public void collectHISDaysBefore(Long daysBefore) {
+        try {
+            // 鑾峰彇daysBefore 0鐐瑰埌daysBefore-1 0鐐圭殑鏃堕棿鑼冨洿
+            LocalDateTime todayZero = LocalDateTime.now().with(LocalTime.MIN);
+            LocalDateTime daysBeforeZeroStart = todayZero.minusDays(daysBefore);
+            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);
+            // 绔嬪嵆杩斿洖锛屽悗鍙板紓姝ユ墽琛�
+            CompletableFuture.runAsync(() -> {
+                ichService.syncMedInhosp(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) {
         if (preachform.equals("-1")) {
             //璇存槑閮戒笉闇�瑕佹墽琛屼簡
@@ -1507,7 +1741,7 @@
 //        //浜哄伐鐨勬湭鍙戦�佺姸鎬侊紝闇�瑕佹煡2
 //        if (preachform.equals("1") && StringUtils.isNotEmpty(failSendstate) && Long.valueOf(failSendstate) > 2)
 //            serviceSubtaskPreachform.setSendstate("2");
-
+        log.error("-----serviceSubtaskPreachform鐨勫叆鍙傛槸锛焮}", serviceSubtaskPreachform);
         List<ServiceSubtaskPreachform> serviceSubtaskPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
         if (CollectionUtils.isNotEmpty(serviceSubtaskPreachforms)) {
             ServiceSubtaskPreachform serviceSubtaskPreachform1 = serviceSubtaskPreachforms.get(0);
@@ -1520,7 +1754,8 @@
             serviceSubtaskPreachformMapper.updateServiceSubtaskPreachform(serviceSubtaskPreachform1);
 
             //濡傛灉褰撳墠鐨刾reachform宸茬粡鏄渶鍚庝竴涓簡锛岄偅鐩存帴灏唖erviceSubtask鐨剆endstate鐘舵�佹敼鎴�7灏辫浜�(鍏ㄨ秴鏃朵簡)
-            if (serviceSubtaskPreachform1.getSort() == sspCount.size()) {
+            if (serviceSubtaskPreachform1.getSort() == sspCount.size()
+                    && isSubtaskDeadline(serviceSubtask, serviceSubtaskPreachforms)) {
                 if (failSendstate.equals("4") || failSendstate.equals("5")) {
                     serviceSubtask.setCurrentPreachform(preachform);
                     serviceSubtask.setSendstate(7L);
@@ -1560,14 +1795,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() : "");
@@ -1598,4 +1834,134 @@
         int result = QwenLLMUtil.matchRegex(questionText, voiceText, value, regexText);
         return result;
     }
+
+    /**
+     * 浠诲姟缁勶紙appltype=5锛夐杞撼鍏ワ細鎵弿鏂板嚭闄㈡偅鑰咃紝鎸� schedule 缁戝畾鐨勭淮搴﹀尮閰嶄换鍔$粍锛�
+     * 涓哄懡涓殑鎮h�呮寜璁″垝鏄庣粏涓�娆℃�х敓鎴愮 0 杞� N 鏉� subtask锛屽苟缃� schedulecheck_flag=1銆�
+     * 鍚庣画杞鐢� {@link #rollTaskGroupCycle()} 璐熻矗銆�
+     * <p>
+     * 涓庝富鎵弿 dealOutHospInfo 鍒嗙锛屼簰涓嶅共鎵般�傚缓璁瘡 30 鍒嗛挓鎵ц涓�娆°��
+     */
+    public void dealTaskGroupOutHosp() {
+        log.info("銆恉ealTaskGroupOutHosp銆戝紑濮嬫壂鎻忎换鍔$粍鏂板嚭闄㈡偅鑰�");
+        if (!port.equals("8095")) {
+            return;
+        }
+        try {
+            String config = configService.selectConfigByKey("visit.early.day");
+            iPatMedInhospService.dealOutHospInfoBySchedule(config);
+            log.info("銆恉ealTaskGroupOutHosp銆戜换鍔$粍棣栬疆绾冲叆鎵弿瀹屾垚");
+        } catch (Exception e) {
+            log.error("銆恉ealTaskGroupOutHosp銆戜换鍔$粍鎵弿寮傚父", e);
+        }
+    }
+
+    /**
+     * 浠诲姟缁勶紙appltype=5锛夊惊鐜换鍔℃粴鍔ㄨ皟搴︺��
+     * <p>
+     * 鎵弿鎵�鏈� schedule_style=1 鐨勮鍒掞紝鑻ユ湰杞� subtask 鍏ㄩ儴 finalize锛坰endstate 鈭� 1/2/3锛夛紝
+     * 鍒欏厠闅嗘湰杞偅鑰呭埌涓嬩竴杞紝鎺ㄨ繘 current_loop_count 涓� visit_time銆�
+     * <p>
+     * 寤鸿姣忓皬鏃舵垨姣忓崐灏忔椂鎵ц涓�娆★紝閬垮厤杞绉帇銆�
+     */
+    public void rollTaskGroupCycle() {
+        log.info("銆恟ollTaskGroupCycle銆戝紑濮嬫壂鎻忓惊鐜换鍔$粍");
+        try {
+            int rolled = serviceTaskScheduleService.rollCycleTasks();
+            log.info("銆恟ollTaskGroupCycle銆戞湰娆℃帹杩� {} 涓鍒�", rolled);
+        } catch (Exception e) {
+            log.error("銆恟ollTaskGroupCycle銆戞粴鍔ㄨ皟搴﹀紓甯�", e);
+        }
+    }
+
+    /**
+     * 闅忚浠诲姟鏄惁瓒呮椂
+     * @param serviceSubtask
+     * @param serviceSubtaskPreachforms
+     * @return
+     */
+    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")){
+                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()))
+                .sum();
+        sumCompensateTime = sumCompensateTime + 1;
+        // 鍙ˉ鍋挎渶鍚庝竴姝ヨ嚜韬殑琛ュ伩鏃堕棿锛堝ぉ锛夛紝鑴忓�间竴寰嬫寜 0 鍏滃簳
+        deadline = DateUtils.addDays(deadline, sumCompensateTime);
+        // 鍑洪櫌(鍙戦��)鏃堕棿 + 鏈琛ュ伩鏃堕棿 灏忎簬褰撳墠鏃堕棿 -> 瓒呮椂
+        return deadline.getTime() < new Date().getTime();
+    }
+
+    /**
+     * 澶勭悊瓒呮椂闅忚浠诲姟
+     * <p>
+     * 鎵弿銆屽嚭闄㈡弧 deadlineDay 澶╀粛鏈畬鎴愩�嶇殑棣栨闅忚浠诲姟锛坰endstate=7 + visit_count=1锛夛紝
+     * 鎸夊綋鍓嶄换鍔$殑 nexttaskid 鐢熸垚鍐嶆闅忚浠诲姟骞惰浆鍒伴殢璁夸腑蹇冦��
+     * <p>
+     * 娉ㄦ剰锛氭埅姝㈡椂闂村繀椤诲湪寰幆澶栬绠椾竴娆°�傚巻鍙插疄鐜版妸 {@code deadlineDay = -deadlineDay}
+     * 鍐欏湪寰幆浣撳唴锛屾瘡杞彇鍙嶄竴娆★紝瀵艰嚧鍋舵暟杞敤銆屼粖澶� + deadlineDay銆嶅仛鎴鏃堕棿锛�
+     * 鎶婂嚭闄笉婊� 28 澶╃殑瓒呮椂浠诲姟涔熸壂浜嗚繘鏉ャ��
+     *
+     * @param orgid       鏈烘瀯ID
+     * @param deadlineDay 鍑洪櫌婊″灏戝ぉ绠楄秴鏃讹紙姝f暟锛屽 28锛�
+     */
+    public void dealSubtaskDeadline(String orgid, Integer deadlineDay){
+        //鑾峰彇浠诲姟淇℃伅
+        ServiceTask st = new ServiceTask();
+        st.setDelFlag("0");
+        st.setLongTask(1);
+        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) {
+            if (ObjectUtils.isEmpty(serviceTask.getNexttaskid())) {
+                continue;
+            }
+            //閫氳繃浠诲姟ID鎷垮埌鎮h�呬俊鎭�,骞朵笖闅忚鏃堕棿寰楁槸浠婂ぉ涔嬪墠鐨�
+            ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity();
+            serviceSubtaskVO.setOrgid(orgid);
+            serviceSubtaskVO.setSendstate(7L);
+            //鍙壂鎻忛娆¢殢璁跨殑
+            serviceSubtaskVO.setVisitCount(1);
+            serviceSubtaskVO.setTaskid(serviceTask.getTaskid());
+            serviceSubtaskVO.setEndOutHospTime(deadline);
+
+            List<ServiceSubtask> serviceSubtaskList
+                    = serviceSubtaskMapper.selectServiceSubtaskList(serviceSubtaskVO);
+            log.info("銆恉ealSubtaskDeadline銆戣幏鍙栧埌{}涓秴鏃朵换鍔�, taskid={}", serviceSubtaskList.size(), serviceTask.getTaskid());
+            for (ServiceSubtask serviceSubtask : serviceSubtaskList) {
+                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