From 1958e8bad428b94aa457734f7f047fe373eafd83 Mon Sep 17 00:00:00 2001
From: 陈昶聿 <chychen@nbjetron.com>
Date: 星期三, 11 十一月 2026 14:06:11 +0800
Subject: [PATCH] Merge branch 'smartor_ls_261103' into smartor_ls_merge

---
 ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java |  758 ++++++++++++++++++++++++++++------------------------------
 1 files changed, 368 insertions(+), 390 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java b/ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java
index 06955a7..e889ed6 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java
@@ -5,32 +5,25 @@
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
 import com.ruoyi.common.core.redis.RedisCache;
-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.exception.base.BaseException;
 import com.ruoyi.common.utils.*;
-import com.ruoyi.common.utils.http.HttpUtils;
-import com.ruoyi.common.utils.sign.Md5Utils;
-import com.ruoyi.common.utils.sms.smsUtils;
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.SmsSendRequest;
+import com.ruoyi.message.sms.SmsSenderFactory;
+import com.ruoyi.message.wechat.WechatSendRequest;
+import com.ruoyi.message.wechat.WechatSenderFactory;
 import com.ruoyi.system.domain.SysConfig;
 import com.ruoyi.system.mapper.SysConfigMapper;
 import com.ruoyi.system.service.ISysConfigService;
-import com.smartor.common.LSHospTokenUtil;
-import com.smartor.common.MtSubmitSmUtil;
 import com.smartor.domain.*;
-import com.smartor.domain.entity.ServiceSubtaskEntity;
 import com.smartor.mapper.*;
 import com.smartor.service.IBaseSmsaccountService;
-import com.smartor.service.IServiceOutPathService;
-import com.smartor.service.IServiceSubtaskRecordService;
 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.data.redis.connection.Message;
@@ -38,18 +31,32 @@
 import org.springframework.data.redis.listener.RedisMessageListenerContainer;
 import org.springframework.stereotype.Component;
 
-import java.io.IOException;
 import java.net.URLEncoder;
-import java.security.MessageDigest;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
-import static cn.hutool.core.convert.Convert.toHex;
-
+import com.ruoyi.template.domain.HeLibrary;
+import com.ruoyi.template.api.TemplateFacade;
+import com.ruoyi.common.core.domain.entity.PatArchive;
+import com.ruoyi.task.domain.entity.ServiceSubtaskEntity;
+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.ServiceOutPath;
+import com.ruoyi.task.service.IServiceOutPathService;
+import com.ruoyi.task.domain.ServiceSubtaskPreachform;
+import com.ruoyi.task.domain.SendMagParam;
+import com.ruoyi.task.service.IServiceSubtaskRecordService;
+import com.ruoyi.task.mapper.ServiceSubtaskPreachformMapper;
+import com.ruoyi.patarchive.mapper.PatArchiveMapper;
 @Slf4j
 @Component//鐩戝惉姝ら槦鍒�
 public class RedisMqReceiver extends KeyExpirationEventMessageListener {
@@ -69,12 +76,26 @@
     @Autowired
     private IServiceOutPathService iServiceOutPathService;
 
+    /**
+     * 妯℃澘鏁版嵁涓�寰嬬粡 ruoyi-template 鐨勯棬闈㈠彇鐢紙璺ㄦā鍧楁暟鎹闂師鍒欙級銆�
+     */
+    @Autowired
+    private TemplateFacade templateFacade;
+
+    /**
+     * 瀹f暀妯″潡鐨�<b>甯搁┗闂ㄩ潰</b>锛岀敤浜庡垽 {@code sys_config: publicity.enabled}銆�
+     * <p>
+     * 鈿狅笍 2025 淇锛氭湰绫诲師鏈�<b>瀹屽叏娌¤瀹f暀寮�鍏�</b> 鈥斺��
+     * {@code tsakHandle} 鐨勫叕浼楀彿 {@code type == 3} 鍒嗘敮锛圠518銆�//瀹f暀銆嶏級
+     * 鐓у父鎷煎鏁欓摼鎺ュ苟鍙戦�侊紝鎵�浠ュ叧鎺� {@code publicity.enabled} 涔熸嫤涓嶄綇杩欐潯璺��
+     */
+    @Autowired
+    private com.ruoyi.publicity.api.PublicityFacade publicityFacade;
+
     @Autowired
     private ServiceSubtaskMapper ivrTaskcallMapper;
 
 
-    @Autowired
-    private HeLibraryMapper heLibraryMapper;
 
     @Autowired
     private ServiceTaskMapper ivrTaskMapper;
@@ -95,31 +116,34 @@
     private ServiceSubtaskPreachformMapper serviceSubtaskPreachformMapper;
 
     @Autowired
+    private ServiceTaskScheduleMapper serviceTaskScheduleMapper;
+
+    @Autowired
+    private ServiceTaskScheduleDetailMapper serviceTaskScheduleDetailMapper;
+
+    @Autowired
     private IServiceSubtaskRecordService serviceSubtaskRecordService;
 
     @Autowired
     IBaseSmsaccountService baseSmsaccountService;
 
-    @Value("${xhsmsPath}")
-    private String xhsmsPath;
-
-    @Value("${xhsmsAccount}")
-    private String xhsmsAccount;
-
-    @Value("${xhsmsPwd}")
-    private String xhsmsPwd;
-    // 铏氭嫙鎺ュ叆鐮�
-    @Value("${xhsmsjrm}")
-    private String xhsmsjrm;
-
     @Value("${server.port}")
     private String port;
 
-    @Value("${spring.profiles.active}")
-    private String active;
+    /**
+     * 娑堟伅鍙戦�佹柟宸ュ巶锛堢煭淇�/寰俊鍏紬鍙凤級銆�
+     * <p>
+     * 鍘熸潵鐭俊涓庡叕浼楀彿鐨勫彂閫侀�昏緫鍦ㄦ湰绫婚噷鐢� {@code if (active.equals("xx"))} 纭垎鏀簡绾� 300 琛岋紝
+     * 鐜板凡鏀跺彛鍒� {@code ruoyi-message} 妯″潡锛岃繖閲屽彧璐熻矗鎸� {@code active} 璺敱銆�
+     */
+    @Autowired
+    private SmsSenderFactory smsSenderFactory;
 
     @Autowired
-    private MtSubmitSmUtil mtSubmitSmUtil;
+    private WechatSenderFactory wechatSenderFactory;
+
+    @Value("${spring.profiles.active}")
+    private String active;
 
     @Autowired
     private ISysConfigService configService;
@@ -222,6 +246,22 @@
                 continue;
             }
             String descByCode = ServiceFromEnum.getDescByCode(Integer.valueOf(sendPreachform));
+
+            // 鈿狅笍 2025 淇锛堝鏁欏紑鍏冲け鏁堬級锛歵ype == 3 鏄�**瀹f暀/閫氱煡**锛堢函鍙戦�併�佹棤浣滅瓟锛�
+            // 瑙� setFailPreachForm 閲屻�屽鏁欐垨閫氱煡鈥︾洿鎺ユ敼鎴� 9銆嶇殑鍒ゅ畾锛夛紝鏁存潯娲惧彂鐨勬墍鏈夐�氶亾
+            // 锛堢數璇�/鐭俊/鍏紬鍙�/浜哄伐锛夊彂鐨勯兘鏄鏁欏唴瀹广�傛墍浠ュ叧鎺� publicity.enabled 鏃�
+            // 搴斿綋**涓�涓�氶亾閮戒笉鍙�**锛岃�屼笉鏄彧鎷﹀叾涓竴娈点��
+            //
+            // 鈿狅笍 鍒绘剰**涓嶆帹杩� subtask 鐘舵�併�佷篃涓嶈澶辫触**锛氬叧闂槸"鏆傛椂涓嶅彂"锛�
+            // 涓嶆槸"杩欎釜鎮h�呬笉闇�瑕佸鏁�"銆傝嫢鏍囨垚澶辫触/涓嶉渶瑕侊紝寮�鍏虫仮澶嶅悗杩欐潯瀹f暀灏辨案杩滀涪浜嗐��
+            // 淇濇寔 sendstate=2 涓嶅姩锛屽紑鍏虫墦寮�鍚庝笅涓�娆℃淳鍙戜細鐓у父鍙戝嚭銆�
+            // 锛堟湰鏂规硶鐨勮皟鐢ㄦ柟 onMessage 澶勭悊瀹屽嵆鍒� Redis 娑堟伅銆佷笉閲嶆姇锛屾墍浠ヤ笉浼氶�犳垚閲嶆姇椋庢毚銆傦級
+            if (type != null && type == 3 && !publicityFacade.isEnabled()) {
+                log.warn("銆愬鏁欍�戞ā鍧楁湭鍚敤锛堝弬鏁伴厤缃� publicity.enabled=false锛夛紝璺宠繃瀹f暀鍙戦�併�俿ubtaskId={}, patid={}",
+                        serviceSubtask.getId(), serviceSubtask.getPatid());
+                continue;
+            }
+
             if (descByCode.equals("鐢佃瘽")) {
                 try {
                     ServiceTask ivrTask = ivrTaskMapper.selectServiceTaskByTaskid(serviceSubtask.getTaskid());
@@ -307,14 +347,14 @@
                         serviceOutPath.setParam6(subId);
                         serviceOutPath.setCreateTime(new Date());
                         serviceOutPath.setOrgid(serviceSubtask.getOrgid());
-                        serviceOutPath.setDeptCode(serviceSubtask.getDeptcode());
+                        serviceOutPath.setDeptCode(serviceSubtask.getLeaveldeptcode());
                         serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode());
-                        serviceOutPath.setDeptName(serviceSubtask.getDeptname());
+                        serviceOutPath.setDeptName(serviceSubtask.getLeaveldeptname());
                         serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname());
                         iServiceOutPathService.insertServiceOutPath(serviceOutPath);
 //                                sendMagParam.setUrl(ip + ":" + req_path + "/followvisit/particty?param1=" + taskId + "&param2=" + patid + "&param5=false");
                         //杞垚16杩涘埗
-                        String format = String.format("%03X", serviceOutPath.getId());
+                        String format = ShortCode.encode(serviceOutPath.getId());
                         serviceOutPath.setRadix(format);
                         serviceOutPath.setUpdateTime(new Date());
                         serviceOutPath.setUrl(ip + ":" + req_path + "/sf?p=" + format);
@@ -345,12 +385,12 @@
                         serviceOutPath.setParam3(ivrTask1.getTaskName());
                         serviceOutPath.setCreateTime(new Date());
                         serviceOutPath.setOrgid(serviceSubtask.getOrgid());
-                        serviceOutPath.setDeptCode(serviceSubtask.getDeptcode());
+                        serviceOutPath.setDeptCode(serviceSubtask.getLeaveldeptcode());
                         serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode());
-                        serviceOutPath.setDeptName(serviceSubtask.getDeptname());
+                        serviceOutPath.setDeptName(serviceSubtask.getLeaveldeptname());
                         serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname());
                         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(StringUtils.isNotEmpty(req_path) ? ip + ":" + req_path + "/wt?p=" + format : ip + "/wt?p=" + format);
@@ -385,15 +425,18 @@
                         serviceOutPath.setParam3(ivrTask1.getTaskName());
                         serviceOutPath.setCreateTime(new Date());
                         serviceOutPath.setOrgid(serviceSubtask.getOrgid());
-                        serviceOutPath.setDeptCode(serviceSubtask.getDeptcode());
+                        serviceOutPath.setDeptCode(serviceSubtask.getLeaveldeptcode());
                         serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode());
-                        serviceOutPath.setDeptName(serviceSubtask.getDeptname());
+                        serviceOutPath.setDeptName(serviceSubtask.getLeaveldeptname());
                         serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname());
                         iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                         String url = "";
-                        String format = String.format("%03X", serviceOutPath.getId());
+                        String format = ShortCode.encode(serviceOutPath.getId());
                         //闇�瑕侀�氳繃妯℃澘ID鍘诲垽鏂鍙戠殑鍐呭鏄鏁欒繕鏄�氱煡
-                        HeLibrary heLibrary = heLibraryMapper.selectHeLibraryById(serviceSubtask.getLibtemplateid());
+                        // 鈿狅笍 涓� RyTask 鍚屽彛寰勶細**鍒绘剰涓�**涓� TemplateModuleDisabledException 闄嶇骇 鈥斺��
+                        // 妯℃澘妯″潡鍏抽棴鏃跺鏁欏唴瀹瑰彇涓嶅埌銆佺煭淇$‘瀹炲彂涓嶅嚭鍘伙紝澶栧眰 try-catch 濡傚疄璁板け璐�
+                        // 骞惰蛋鏃㈡湁鐨勯�氶亾鍗囩骇鏈哄埗銆傜‖璁版垚鍔熺瓑浜庣敤鍋囪褰曟帺鐩�"娌″彂鍑哄幓"銆�
+                        HeLibrary heLibrary = templateFacade.findHeLibraryById(serviceSubtask.getLibtemplateid());
                         if (heLibrary.getHetype().equals("1")) {
                             sendMagParam.setPhone(serviceSubtask.getPhone());
                             url = StringUtils.isNotEmpty(req_path) ? ip + ":" + req_path + "/xj?p=" + format : ip + "/xj?p=" + format;
@@ -426,120 +469,11 @@
                         iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                     }
 
-                    //鐭俊杩橀渶瑕佹ā鏉�
-                    String s = null;
-                    if (active.equals("xh")) {
-                        //鏂板崕鐨勭煭淇″彂閫佹柟寮�
-                        Map<String, String> map2 = new HashMap<String, String>();
-                        map2.put("action", "send");
-                        map2.put("account", xhsmsAccount);
-                        map2.put("password", xhsmsPwd);
-                        map2.put("mobile", sendMagParam.getPhone());
-                        map2.put("content", sendMagParam.getContent());
-                        map2.put("extno", xhsmsjrm);
-                        map2.put("rt", "json");
-                        StringBuilder encodedParams = new StringBuilder();
-
-                        for (Map.Entry<String, String> entry : map2.entrySet()) {
-                            if (encodedParams.length() > 0) {
-                                encodedParams.append("&");
-                            }
-                            // 瀵归敭鍜屽�艰繘琛孶RL缂栫爜
-                            String encodedKey = URLEncoder.encode(entry.getKey(), "UTF-8");
-                            String encodedValue = URLEncoder.encode(entry.getValue(), "UTF-8");
-                            encodedParams.append(encodedKey).append("=").append(encodedValue);
-                        }
-                        Boolean isSuccess = HttpUtil.postJsonRequest(xhsmsPath, encodedParams.toString());
-                        if (isSuccess) s = "true";
-                    } else if (active.equals("ls")) {
-                        //涓芥按鐨勭煭淇″彂閫佹柟寮�
-                        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.isNotEmpty(msgInfo) && StringUtils.isEmpty(msgInfo.get("address"))) {
-                            serviceSubtask.setCurrentPreachform(sendPreachform);
-                            serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime(), serviceSubtask.getCurrentPreachform()));
-                            setFailPreachForm(serviceSubtask, descByCode, "鐭俊鍙戦�佸け璐�,璇ユ満鏋勬病鏈夐厤缃煭淇″湴鍧�", "5");
-                            serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
-                            continue;
-                        }
-
-                        String token = LSHospTokenUtil.getToken(serviceSubtask.getOrgid(), msgInfo.get("tokenUrl"));
-                        String dxCode = getDXCode(msgInfo.get("address"), sendMagParam.getPhone(), sendMagParam.getContent(), msgInfo.get("sendPersonId"), msgInfo.get("sendPersonName"), MsgLSEnum.getHeaderByCode(msgInfo), token);
-                        ObjectMapper objectMapper = new ObjectMapper();
-                        Map<String, Object> textParam = objectMapper.readValue(dxCode, Map.class);
-                        String code = textParam.get("Code").toString();
-                        if (code.equals("0")) {
-                            s = "true";
-                        } else {
-                            setFailPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�", "5");
-                            throw new BaseException("鐭俊鍙戦�佸け璐�");
-                        }
-                    } else if (active.equals("sltd") || active.equals("nhfy")) {
-                        //鐪佺珛鍚屽痉鐨勭煭淇″彂閫佹柟寮�
-                        String data = null;
-                        Map<String, Object> smsResult = null;
-                        if (active.equals("sltd")) {
-                            data = MessageSend.sendMsg(sendMagParam.getContent(), "6", sendMagParam.getPhone(), LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
-                            if (StringUtils.isNotEmpty(data)) {
-                                String[] pairs = data.split("&");
-                                String resultVal = null;
-                                for (String pair : pairs) {
-                                    String[] kv = pair.split("=", 2);
-                                    if ("result".equals(kv[0])) {
-                                        resultVal = kv.length > 1 ? kv[1] : null;
-                                        break;
-                                    }
-                                }
-                                if ("0".equals(resultVal)) {
-                                    s = "true";
-                                }
-                            } else {
-                                setFailPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�: " + data, "5");
-                                throw new BaseException("鐭俊鍙戦�佸け璐�");
-                            }
-                        } else if (active.equals("nhfy")) {
-                            smsResult = mtSubmitSmUtil.submitSm(sendMagParam.getPhone(), sendMagParam.getContent());
-                            if (smsResult != null && smsResult.get("result") != null && smsResult.get("result").toString().equals("0")) {
-                                s = "true";
-                            } else {
-                                setFailPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�", "5");
-                                throw new BaseException("鐭俊鍙戦�佸け璐�");
-                            }
-                        }
-
-                    } else if (active.equals("hzszlyy")) {
-                        //甯備竴
-                        long timestamp = new Date().getTime();
-                        String sign = Md5Utils.hash(xhsmsAccount + timestamp + Md5Utils.hash(xhsmsPwd));
-                        String content = sendMagParam.getContent();
-                        String jsonMsg = "{" + "\"userName\": \"" + xhsmsAccount + "\"," + "\"content\": \"" + content + "\"," + "\"phoneList\": [" + sendMagParam.getPhone() + "]," + "\"timestamp\": " + timestamp + "," + "\"sign\": \"" + sign + "\"" + "}";
-                        Boolean b = HttpUtil.postJsonRequest(xhsmsPath, jsonMsg);
-                        if (b) s = "true";
-                        log.info("------甯備竴鐭俊鍙戦�佺殑鍊间负锛歿}", s);
-                        if (StringUtils.isNotEmpty(s)) {
-                            JSONObject jsonObject = JSONObject.parseObject(s);
-                            Object code = jsonObject.get("code");
-                            if (code.equals(0)) {
-                                s = "true";
-                            } else {
-                                setFailPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�", "5");
-                                throw new BaseException("鐭俊鍙戦�佸け璐�");
-                            }
-                        }
-                    }
-                    if (s.equals("true")) {
+                    //鐭俊鍙戦�侊細鍚勭珯鐐瑰鎺ユ柟寮忓樊寮傝緝澶э紙鎶ユ枃/绛惧悕/token/杩斿洖鍒ゅ畾閮戒笉鍚岋級锛�
+                    //宸叉敹鍙e埌 ruoyi-message 妯″潡锛岃繖閲屽彧璐熻矗缁勮鍏ュ弬骞惰矾鐢�
+                    log.info("----active鐨勫�间负锛歿}", active);
+                    SendResult smsSendResult = sendSmsByActive(serviceSubtask, sendMagParam);
+                    if (smsSendResult.isOk()) {
                         //鍦ㄥ瓙浠诲姟琛ㄩ噷璁板綍涓�涓�
                         setFailPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佹垚鍔�", "2");
                         //浠诲姟鍙戦�佽褰�
@@ -553,10 +487,10 @@
                         serviceSubtaskRecord.setResult("success");
                         serviceSubtaskRecord.setRemark("鐭俊鍙戦�佹垚鍔�");
                         serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
-                        log.error("serviceSubtaskRecord淇濆瓨鎴愬姛浜嗗悧锛燂細{}", serviceSubtaskRecord);
                     } else {
                         //鍦ㄥ瓙浠诲姟琛ㄩ噷璁板綍涓�涓�
                         setFailPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�", "5");
+                        continue;
                     }
                 } catch (Exception e) {
                     ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
@@ -593,12 +527,12 @@
                         serviceOutPath.setParam6(subId);
                         serviceOutPath.setCreateTime(new Date());
                         serviceOutPath.setOrgid(serviceSubtask.getOrgid());
-                        serviceOutPath.setDeptCode(serviceSubtask.getDeptcode());
+                        serviceOutPath.setDeptCode(serviceSubtask.getLeaveldeptcode());
                         serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode());
-                        serviceOutPath.setDeptName(serviceSubtask.getDeptname());
+                        serviceOutPath.setDeptName(serviceSubtask.getLeaveldeptname());
                         serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname());
                         iServiceOutPathService.insertServiceOutPath(serviceOutPath);
-                        String format = String.format("%03X", serviceOutPath.getId());
+                        String format = ShortCode.encode(serviceOutPath.getId());
                         serviceOutPath.setRadix(format);
                         serviceOutPath.setUpdateTime(new Date());
                         url = ip + ":" + req_path + "/sf?p=" + format;
@@ -613,12 +547,12 @@
                         serviceOutPath.setParam6(subId);
                         serviceOutPath.setCreateTime(new Date());
                         serviceOutPath.setOrgid(serviceSubtask.getOrgid());
-                        serviceOutPath.setDeptCode(serviceSubtask.getDeptcode());
+                        serviceOutPath.setDeptCode(serviceSubtask.getLeaveldeptcode());
                         serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode());
-                        serviceOutPath.setDeptName(serviceSubtask.getDeptname());
+                        serviceOutPath.setDeptName(serviceSubtask.getLeaveldeptname());
                         serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname());
                         iServiceOutPathService.insertServiceOutPath(serviceOutPath);
-                        String format = String.format("%03X", serviceOutPath.getId());
+                        String format = ShortCode.encode(serviceOutPath.getId());
 
                         url = StringUtils.isNotEmpty(req_path) ? ip + ":" + req_path + "/wt?p=" + format : ip + "/wt?p=" + format;
                         //濡傛灉type鏄闊抽殢璁跨殑璇濓紙璇存槑琛ュ伩鍙戦�佹柟寮忎腑鏈夌數璇濋殢璁跨殑鏂瑰紡锛岃繖閲岀殑澶栭摼灏卞湴鍧�鍙兘鐢�/sf锛�
@@ -637,16 +571,16 @@
                         serviceOutPath.setParam3(ivrTask1.getTaskName());
                         serviceOutPath.setParam6(subId);
                         serviceOutPath.setCreateTime(new Date());
-                        serviceOutPath.setDeptCode(serviceSubtask.getDeptcode());
+                        serviceOutPath.setDeptCode(serviceSubtask.getLeaveldeptcode());
                         serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode());
-                        serviceOutPath.setDeptName(serviceSubtask.getDeptname());
+                        serviceOutPath.setDeptName(serviceSubtask.getLeaveldeptname());
                         serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname());
                         serviceOutPath.setOrgid(serviceSubtask.getOrgid());
                         iServiceOutPathService.insertServiceOutPath(serviceOutPath);
-                        String format = String.format("%03X", serviceOutPath.getId());
+                        String format = ShortCode.encode(serviceOutPath.getId());
 
                         //闇�瑕侀�氳繃妯℃澘ID鍘诲垽鏂鍙戠殑鍐呭鏄鏁欒繕鏄�氱煡
-//                        HeLibrary heLibrary = heLibraryMapper.selectHeLibraryById(serviceSubtask.getLibtemplateid());
+//                        HeLibrary heLibrary = templateFacade.findHeLibraryById(serviceSubtask.getLibtemplateid());
 //                        if (heLibrary.getHetype().equals("1")) {
 //                            sendMagParam.setPhone(serviceSubtask.getPhone());
 //                            sendMagParam.setUrl(ip + ":" + req_path + "/xj?p=" + format);
@@ -668,58 +602,28 @@
                         serviceOutPath.setUrl(url);
                         iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                     }
-                    if (StringUtils.isEmpty(patArchive.getPatidHis())) {
-                        serviceSubtask.setCurrentPreachform(sendPreachform);
-                        serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime(), serviceSubtask.getCurrentPreachform()));
-                        serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
-                        //澶辫触璁板綍
-                        setFailPreachForm(serviceSubtask, sendPreachform, "鍏紬鍙峰彂閫佸け璐�,his绯荤粺鐨勬偅鑰卛d涓虹┖", "5");
-                        continue;
-                    }
-
-                    //鑾峰彇寰俊鍏紬鍙疯姹備俊鎭牴鎹満鏋処D
+                    //鏈烘瀯閰嶇疆鏍¢獙锛圵xGZHEnum锛変笌 his 鎮h�卛d 鏍¢獙宸叉敹鍙e埌
+                    //ruoyi-message 鐨� WechatMpConfigProvider / XinHuaMpSender锛岃皟鐢ㄧ偣涓嶅啀閲嶅鏍¢獙
                     log.error("鑾峰彇寰俊鍏紬鍙疯姹備俊鎭牴鎹満鏋処D锛歿}", patArchive.getOrgid());
-                    List<String> wxqqxx = WxGZHEnum.getDescByCode(patArchive.getOrgid());
-                    //甯備竴鍖婚櫌 涓嶆牎楠�
-                    if (CollectionUtils.isEmpty(wxqqxx) || wxqqxx.size() < 4) {
-                        serviceSubtask.setCurrentPreachform(sendPreachform);
-                        serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime(), serviceSubtask.getCurrentPreachform()));
-                        serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
-
-                        //澶辫触璁板綍
-                        setFailPreachForm(serviceSubtask, sendPreachform, "璇ユ満鏋勭殑鍏紬鍙烽厤缃俊鎭笉鍏紝鏃犳硶閫氳繃鍏紬鍙峰彂閫�", "5");
-                        continue;
-                    }
-                    String wxCode = "";
-                    if (active.equals("hzszlyy")) {
-                        wxCode = smsUtils.sendChat(url, patArchive.getTelcode(), serviceSubtask.getSfzh());
-                        log.info("wxCode鐨勫�间负:{}", wxCode);
+                    if (!"xh".equals(active)) {
+                        //甯備竴锛氳蛋鑷湁鍏紬鍙风綉鍏筹紙涓嶅仛鏈烘瀯閰嶇疆鏍¢獙銆乭is鎮h�卛d鏍¢獙锛屼笌鍘熷疄鐜颁竴鑷达級
+                        sendWechatByActive(serviceSubtask, patArchive, url);
                     } else {
-                        wxCode = getWXCode(serviceSubtask.getSfzh(), url, serviceSubtask.getTaskName(), serviceSubtask.getTaskName(), patArchive.getTelcode(), patArchive.getName(), patArchive.getPatidHis(), wxqqxx);
-                        log.error("wxCode鐨勫�间负:{}", wxCode);
-                        Map<String, Object> map = JSONObject.parseObject(wxCode, Map.class);
-                        log.error("map鐨勫�间负:{}", map);
-                        if (!map.isEmpty()) {
-                            serviceSubtask.setResult("success");
-                            serviceSubtask.setSendstate(3L);
-                            log.error("aBoolean鐨勫�间负:{}", aBoolean);
-                            if (map.get("succ").toString().equals("true")) {
-                                aBoolean = true;
-                            }
-                            if (aBoolean == false) {
-                                ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
-                                serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
-                                serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
-                                serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
-                                serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
-                                serviceSubtaskRecord.setPreachform("5");
-                                serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
-                                serviceSubtaskRecord.setRemark(ObjectUtils.isNotEmpty(map.get("msg")) ? map.get("msg").toString() : null);
-                                serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
-                                //鍦ㄥ瓙浠诲姟琛ㄩ噷璁板綍涓�涓�
-                                setFailPreachForm(serviceSubtask, sendPreachform, "鍏紬鍙峰彂閫佸け璐�", "5");
-                                continue;
-                            }
+                        //鏂板崕锛歨is鎮h�卛d鏍¢獙澶辫触鍗宠褰曞苟杩涘叆涓嬩竴绉嶅彂閫佹柟寮�
+                        SendResult wechatSendResult = sendWechatByActive(serviceSubtask, patArchive, url);
+                        if (!wechatSendResult.isOk()) {
+                            ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
+                            serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
+                            serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
+                            serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
+                            serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
+                            serviceSubtaskRecord.setPreachform("5");
+                            serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
+                            serviceSubtaskRecord.setRemark(wechatSendResult.getMessage());
+                            serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
+                            //鍦ㄥ瓙浠诲姟琛ㄩ噷璁板綍涓�涓�
+                            setFailPreachForm(serviceSubtask, sendPreachform, "鍏紬鍙峰彂閫佸け璐�", "5");
+                            continue;
                         }
                     }
                 } catch (Exception e) {
@@ -739,10 +643,15 @@
                     continue;
                 }
                 //鍦ㄥ瓙浠诲姟琛ㄩ噷璁板綍涓�涓�
-                setFailPreachForm(serviceSubtask, sendPreachform, "鍏紬鍙峰彂閫佹垚鍔�", "2");
+                Boolean stateUpdated = setFailPreachForm(serviceSubtask, sendPreachform, "鍏紬鍙峰彂閫佹垚鍔�", "2");
+                if (!Boolean.TRUE.equals(stateUpdated)) {
+                    log.error("鍏紬鍙峰彂閫佹垚鍔熶絾鏇存柊瀛愪换鍔$姸鎬佸け璐ワ紝subid锛歿}锛宲reachform锛歿}", serviceSubtask.getId(), sendPreachform);
+                    continue;
+                }
                 //浠诲姟鍙戦�佽褰�
                 ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                 serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
+                serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
                 serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
                 serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
                 serviceSubtaskRecord.setPreachform("5");
@@ -758,6 +667,52 @@
             }
         }
 
+    }
+
+    /**
+     * 鎸� {@code active}锛堢珯鐐癸級璺敱鍒板搴旂殑鐭俊鍙戦�佹柟銆�
+     * <p>
+     * 鍏ュ弬娌跨敤鍘熷垎鏀噷宸茬粡缁勮濂界殑 {@code SendMagParam}锛屼繚璇佸唴瀹逛笌绾夸笂瀹屽叏涓�鑷淬��
+     * 鍚勭珯鐐瑰樊寮傝 {@code ruoyi-message} 妯″潡鍚勫疄鐜扮被銆�
+     * <p>
+     * 鈿狅笍 鏂板崕锛坽@code xh}锛夊湪鏈叆鍙e師鏈蛋銆孶RL 缂栫爜琛ㄥ崟銆嶏紝
+     * 涓� {@code RyTask}锛堝彂绌烘姤鏂囷級/ {@code smsSubTask}锛圝SON锛夊苟涓嶄竴鑷达紱
+     * 杩欓噷鎸夊師鏍疯蛋 {@code XinHuaSmsSender#sendForm}锛堣〃鍗曟ā寮忥級銆�
+     */
+    private SendResult sendSmsByActive(ServiceSubtask serviceSubtask, SendMagParam sendMagParam) {
+        SmsSendRequest request = SmsSendRequest.of(
+                sendMagParam.getPhone(), sendMagParam.getContent(), serviceSubtask.getOrgid());
+        return smsSenderFactory.send(active, request);
+    }
+
+    /**
+     * 鎸� {@code active}锛堢珯鐐癸級璺敱鍒板搴旂殑寰俊鍏紬鍙峰彂閫佹柟銆�
+     * <p>
+     * 鈿狅笍 绔欑偣宸紓锛堜笌鍘熷疄鐜颁竴涓�瀵瑰簲锛夛細
+     * <ul>
+     *   <li>甯備竴锛坽@code hzszlyy}锛夛細涓嶅仛 his 鎮h�卛d 鏍¢獙锛屾爣棰�/鍐呭閮藉彇浠诲姟鍚嶇О锛�</li>
+     *   <li>鏂板崕锛坽@code xh}锛夛細瑕佹眰 his 鎮h�卛d 闈炵┖锛屾偅鑰呭鍚嶅彇 {@code patArchive.getName()}锛�</li>
+     *   <li>鏂板崕鐨� JSON 鎶ユ枃浣撻渶瑕� {@code disableHtmlEscaping}锛屼笌 {@code RyTask} 涓嶅悓銆�</li>
+     * </ul>
+     */
+    private SendResult sendWechatByActive(ServiceSubtask serviceSubtask, PatArchive patArchive, String url) {
+        if (StringUtils.isEmpty(patArchive.getPatidHis())) {
+            return SendResult.fail(active, MessageChannel.WECHAT,
+                    "鍏紬鍙峰彂閫佸け璐�,his绯荤粺鐨勬偅鑰卛d涓虹┖", null);
+        }
+        WechatSendRequest request = new WechatSendRequest();
+        request.setOrgid(patArchive.getOrgid());
+        request.setIdCard(serviceSubtask.getSfzh());
+        request.setUrl(url);
+        request.setTitle(serviceSubtask.getTaskName());
+        //鍘熷疄鐜版爣棰樹笌鍐呭閮戒紶 serviceSubtask.getTaskName()
+        request.setContent(serviceSubtask.getTaskName());
+        request.setPhone(patArchive.getTelcode());
+        request.setPatientName(patArchive.getName());
+        request.setPatidHis(patArchive.getPatidHis());
+        //鍘� RedisMqReceiver.getWXCode 浣跨敤 disableHtmlEscaping锛屼笌 RyTask 涓嶅悓锛屾澶勪繚鎸�
+        request.setDisableHtmlEscaping(true);
+        return wechatSenderFactory.send(active, request);
     }
 
     private String getSC(ServiceSubtask serviceSubtask, String scriptContent) {
@@ -793,15 +748,15 @@
         List<ServiceSubtaskPreachform> serviceSubtaskPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
 
         if (CollectionUtils.isNotEmpty(serviceSubtaskPreachforms)) {
-            Optional<String> ct = serviceSubtaskPreachforms.stream().filter(item -> currentPreachform.equals(item.getPreachform())).map(ServiceSubtaskPreachform::getCompensateTime).findFirst();
-            String compensateTime = "0";
-            if (ct.isPresent()) compensateTime = ct.get();
-            int hoursToAdd = Integer.valueOf(compensateTime) * 24;
+            Optional<String> ct = serviceSubtaskPreachforms.stream()
+                    .filter(item -> Objects.equals(currentPreachform, item.getPreachform()))
+                    .map(ServiceSubtaskPreachform::getCompensateTime)
+                    .findFirst();
+            int daysToAdd = ct.map(value -> NumberUtils.toInt(value, 0)).orElse(0);
             Calendar calendar = Calendar.getInstance();
-            calendar.setTime(visitTime);
-            calendar.add(Calendar.HOUR_OF_DAY, hoursToAdd);
-            Date newDate = calendar.getTime();
-            return newDate;
+            calendar.setTime(visitTime == null ? new Date() : visitTime);
+            calendar.add(Calendar.HOUR_OF_DAY, daysToAdd * 24);
+            return calendar.getTime();
         }
         return visitTime;
     }
@@ -896,7 +851,7 @@
      */
     public Boolean setFailPreachForm(ServiceSubtask serviceSubtask, String preachform, String remark, String failSendstate) {
         log.info("^^^^^^^^^--------setFailPreachForm鐨勫叆鍙備负serviceSubtask锛歿}   锛宲reachform鍊间负锛歿}锛�  failSendstate锛歿}", serviceSubtask, preachform, failSendstate);
-        if (preachform.equals("-1")) {
+        if ("-1".equals(preachform)) {
             //璇存槑閮戒笉闇�瑕佹墽琛屼簡
             ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
             serviceSubtaskPreachform.setSubid(serviceSubtask.getId());
@@ -904,73 +859,142 @@
             serviceSubtaskPreachform.setOrgid(serviceSubtask.getOrgid());
             serviceSubtaskPreachform.setSendstate(failSendstate);
             serviceSubtaskPreachform.setCurrentSendTime(new Date());
-            if (serviceSubtask.getType().equals("3") || serviceSubtask.getType().equals("4")) {
+            if (isEducationOrNotice(serviceSubtask) && "2".equals(failSendstate)) {
                 //濡傛灉鏄鏁欐垨閫氱煡锛屽苟涓斿彂閫佹垚鍔燂紝鐩存帴灏嗗彂閫佺姸鎬佹敼鎴�9
-                if (failSendstate.equals("2")) serviceSubtaskPreachform.setSendstate("9");
+                serviceSubtaskPreachform.setSendstate("9");
             }
             serviceSubtaskPreachformMapper.updateSSPByCondition(serviceSubtaskPreachform);
 
             return true;
         }
 
-        //灏嗙姸鎬佽缃负澶辫触
-        ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
-        serviceSubtaskPreachform.setSubid(serviceSubtask.getId());
-        serviceSubtaskPreachform.setTaskid(serviceSubtask.getTaskid());
-        serviceSubtaskPreachform.setOrgid(serviceSubtask.getOrgid());
-        //鑾峰彇璇ユ偅鑰呯殑鍙戦�佹柟寮忔�绘暟
-        List<ServiceSubtaskPreachform> spSize = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
-        log.error("-------spSize鐨勫�间负锛歿}", spSize);
-        serviceSubtaskPreachform.setPreachform(preachform);
-        //1:鏈彂閫佺姸鎬�
-        serviceSubtaskPreachform.setSendstate("1");
-        log.info("---serviceSubtaskPreachform鍏ュ弬涓猴細{}", serviceSubtaskPreachform);
-        List<ServiceSubtaskPreachform> serviceSubtaskPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
-        log.info("---serviceSubtaskPreachform杩斿弬涓猴細{}", serviceSubtaskPreachforms);
-        //鐢佃瘽鐨勬湭鍙戦�佺姸鎬侊紝闇�瑕佹煡2锛屽洜涓猴紝鏁版嵁鍙兘鍗″湪闃熷垪閲屼簡(涔熸湁鍙兘娌℃湁鎷夊彇锛宻endstate=1,鎵�浠ュ鏋滄槸鐢佃瘽鐘舵�佸垽鏂璼erviceSubtaskPreachforms鏄笉鏄负绌�)
-        if (preachform.equals("3") && CollectionUtils.isEmpty(serviceSubtaskPreachforms)) {
-            serviceSubtaskPreachform.setSendstate("2");
-            serviceSubtaskPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
-        }
-        if (CollectionUtils.isNotEmpty(serviceSubtaskPreachforms)) {
-            ServiceSubtaskPreachform serviceSubtaskPreachform1 = serviceSubtaskPreachforms.get(0);
-            serviceSubtaskPreachform1.setSendstate(failSendstate);
-            if (serviceSubtask.getType().equals("3") || serviceSubtask.getType().equals("4")) {
-                //濡傛灉鏄鏁欐垨閫氱煡锛屽苟涓斿彂閫佹垚鍔燂紝鐩存帴灏嗗彂閫佺姸鎬佹敼鎴�9
-                if (failSendstate.equals("2")) serviceSubtaskPreachform1.setSendstate("9");
-            }
-            serviceSubtaskPreachform1.setRemark(remark);
-            serviceSubtaskPreachformMapper.updateServiceSubtaskPreachform(serviceSubtaskPreachform1);
-            //濡傛灉褰撳墠鐨刾reachform宸茬粡鏄渶鍚庝竴涓簡,骞朵笖鏈杩樻槸鍙戦�佸け璐ワ紝閭g洿鎺ュ皢serviceSubtask鐨剆endstate鐘舵�佹敼鎴�5灏辫浜�(鍏ㄥけ璐ヤ簡)
-            if (CollectionUtils.isNotEmpty(spSize) && serviceSubtaskPreachform1.getSort() == spSize.size()
-                    && isSubtaskDeadline(serviceSubtask, serviceSubtaskPreachforms)) {
-                if (serviceSubtaskPreachform1.getSort() == spSize.size()) {
-                    if (failSendstate.equals("4") || failSendstate.equals("5")) {
-                        serviceSubtask.setCurrentPreachform(preachform);
-                        serviceSubtask.setSendstate(7L);
-                        serviceSubtask.setFinishtime(null);
-                        serviceSubtask.setRemark("澶勭悊琛ュ伩浠诲姟,褰撳墠澶勭悊鏈�鍚庤ˉ鍋匡紝鍏ㄩ儴鎵ц澶辫触(瓒呮椂)");
-                        serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
-                        return true;
-                    }
-                }
-            }
-        } else {
+        // 鏌ヨ璇ュ瓙浠诲姟鐨勫叏閮ㄥ彂閫佹柟寮忥紝涓嶅啀鍙煡 sendstate=1銆�
+        // 绗竴娆″彂閫佸悗璇ヨ鍙兘宸茬粡鍙樻垚 sendstate=2锛岄噸璇曟椂浠嶉渶瑕佸畾浣嶅埌鍚屼竴琛屻��
+        ServiceSubtaskPreachform query = new ServiceSubtaskPreachform();
+        query.setSubid(serviceSubtask.getId());
+        query.setTaskid(serviceSubtask.getTaskid());
+        query.setOrgid(serviceSubtask.getOrgid());
+        List<ServiceSubtaskPreachform> allPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(query);
+        log.info("---serviceSubtaskPreachform杩斿弬涓猴細{}", allPreachforms);
+        if (CollectionUtils.isEmpty(allPreachforms)) {
             log.error("銆怣Q涓鎮h�呮病鏈夋煡璇㈠埌灞炰簬浠栫殑鍙戦�佹柟寮忥紝subid锛歿},prechform:{},orgid:{}銆�", serviceSubtask.getId(), preachform, serviceSubtask.getOrgid());
             return false;
         }
-        log.info("^^^^^^^^^--------preachform鐨勫�间负锛歿}", preachform);
+
+        // 鎸� getSendPreachform 鐨勯�夋嫨瑙勫垯瀹氫綅鏈瀹為檯澶勭悊鐨勫彂閫佹柟寮忚銆�
+        ServiceSubtaskPreachform currentPreachformRow = findCurrentPreachformRow(allPreachforms, serviceSubtask, preachform);
+        if (currentPreachformRow == null) {
+            log.error("銆怣Q涓鎮h�呮病鏈夋煡璇㈠埌褰撳墠鍙戦�佹柟寮忥紝subid锛歿},prechform:{},orgid:{}銆�", serviceSubtask.getId(), preachform, serviceSubtask.getOrgid());
+            return false;
+        }
+
+        // 鍏堣惤搴� service_subtask 鐘舵�侊紝鍐嶆洿鏂板彂閫佹柟寮忔槑缁嗐��
+        // 杩欐牱鍗充娇鍚庣画姝ラ寮傚父锛�60 绉掗噸璇曚篃涓嶄細鍐嶆閫変腑骞跺彂閫併��
         serviceSubtask.setCurrentPreachform(preachform);
-        serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime(), serviceSubtask.getCurrentPreachform()));
+        serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime(), preachform));
         serviceSubtask.setSendstate(3L);
-        if (serviceSubtask.getType().equals("3") || serviceSubtask.getType().equals("4")) {
+        if (isEducationOrNotice(serviceSubtask) && "2".equals(failSendstate)) {
             //濡傛灉鏄鏁欐垨閫氱煡锛屽苟涓斿彂閫佹垚鍔燂紝鍒欑洿鎺ュ皢serviceSubtask鐘舵�佹敼鎴�6L锛堣繖涓偅鑰呮槸娌℃湁棰樺仛鐨勶紝涓嶄細鍐嶈Е鍙戞帴鍙h繘琛岀姸鎬佷慨鏀癸級
-            if (failSendstate.equals("2")) {
-                serviceSubtask.setSendstate(6L);
-            }
+            serviceSubtask.setSendstate(6L);
         }
         serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
+
+        // 鏇存柊褰撳墠鍙戦�佹柟寮忔槑缁嗭紱鍙戦�佹垚鍔熸椂鍏佽褰撳墠琛屽凡缁忔槸 sendstate=2銆�
+        currentPreachformRow.setSendstate(failSendstate);
+        if (isEducationOrNotice(serviceSubtask) && "2".equals(failSendstate)) {
+            currentPreachformRow.setSendstate("9");
+        }
+        currentPreachformRow.setRemark(remark);
+        serviceSubtaskPreachformMapper.updateServiceSubtaskPreachform(currentPreachformRow);
+
+        // 鍙湁鏈�鍚庝竴姝ヤ笖鍙戦�佸け璐ワ紙4/5锛夋椂鎵嶉渶瑕佸垽鏂秴鏃跺苟缃负 7銆�
+        boolean lastStep = currentPreachformRow.getSort() != null
+                && currentPreachformRow.getSort() == allPreachforms.size();
+        if (lastStep && ("4".equals(failSendstate) || "5".equals(failSendstate))
+                && isSubtaskDeadline(serviceSubtask, allPreachforms)) {
+            serviceSubtask.setSendstate(7L);
+            serviceSubtask.setFinishtime(null);
+            serviceSubtask.setRemark("澶勭悊琛ュ伩浠诲姟,褰撳墠澶勭悊鏈�鍚庤ˉ鍋匡紝鍏ㄩ儴鎵ц澶辫触(瓒呮椂)");
+            serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
+        }
         return true;
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁涓哄鏁欐垨閫氱煡绫诲瀷銆�
+     */
+    private boolean isEducationOrNotice(ServiceSubtask serviceSubtask) {
+        return serviceSubtask != null
+                && ("3".equals(serviceSubtask.getType()) || "4".equals(serviceSubtask.getType()));
+    }
+
+    /**
+     * 瀹氫綅鏈瀹為檯澶勭悊鐨勫彂閫佹柟寮忚銆�
+     * 閫夋嫨瑙勫垯涓� getSendPreachform 淇濇寔涓�鑷达細
+     * 1. current_preachform 涓虹┖鏃跺彇 sort=1锛�
+     * 2. current_preachform 涓嶄负绌烘椂鍙� current_preachform 瀵瑰簲 sort 鐨勪笅涓�姝ワ紱
+     * 3. 鍏滃簳鎸夊彂閫佹柟寮忓尮閰嶏紝浼樺厛鍙� current_send_time 鏈�杩戠殑涓�琛岋紝鍐嶅彇 sort 杈冨皬鐨勪竴琛屻��
+     */
+    private ServiceSubtaskPreachform findCurrentPreachformRow(List<ServiceSubtaskPreachform> rows,
+                                                              ServiceSubtask serviceSubtask,
+                                                              String preachform) {
+        if (StringUtils.isEmpty(serviceSubtask.getCurrentPreachform())) {
+            for (ServiceSubtaskPreachform row : rows) {
+                if (Objects.equals(preachform, row.getPreachform())
+                        && row.getSort() != null && row.getSort() == 1L) {
+                    return row;
+                }
+            }
+        } else {
+            Long currentSort = null;
+            for (ServiceSubtaskPreachform row : rows) {
+                if (Objects.equals(serviceSubtask.getCurrentPreachform(), row.getPreachform())) {
+                    currentSort = row.getSort();
+                    break;
+                }
+            }
+            if (currentSort != null) {
+                Long nextSort = currentSort + 1;
+                for (ServiceSubtaskPreachform row : rows) {
+                    if (Objects.equals(nextSort, row.getSort())
+                            && Objects.equals(preachform, row.getPreachform())) {
+                        return row;
+                    }
+                }
+            }
+        }
+
+        ServiceSubtaskPreachform target = null;
+        for (ServiceSubtaskPreachform row : rows) {
+            if (!Objects.equals(preachform, row.getPreachform())) {
+                continue;
+            }
+            if (target == null) {
+                target = row;
+                continue;
+            }
+            Date rowTime = row.getCurrentSendTime();
+            Date targetTime = target.getCurrentSendTime();
+            if (rowTime != null && (targetTime == null || rowTime.after(targetTime))) {
+                target = row;
+            } else if (Objects.equals(rowTime, targetTime) && comparePreachformSort(row, target) < 0) {
+                target = row;
+            }
+        }
+        return target;
+    }
+
+    private int comparePreachformSort(ServiceSubtaskPreachform row, ServiceSubtaskPreachform target) {
+        if (row.getSort() == null && target.getSort() == null) {
+            return 0;
+        }
+        if (row.getSort() == null) {
+            return 1;
+        }
+        if (target.getSort() == null) {
+            return -1;
+        }
+        return row.getSort().compareTo(target.getSort());
     }
 
     private String getKey() {
@@ -995,106 +1019,12 @@
         return targetKey;
     }
 
-//    private String getKey() {
-//        Map<String, List> map = new HashMap<>();
-//        for (int i = 0; i < 6; i++) {
-//            Boolean aBoolean = redisCache.hasKey("cache-" + i);
-//            if (!aBoolean) {
-//                redisCache.setCacheList("cache-" + i, new ArrayList<String>());
-//                map.put("cache-" + i, new ArrayList<String>());
-//            } else {
-//                map.put("cache-" + i, redisCache.getCacheObject("cache-" + i));
-//            }
-//        }
-//
-//        String key = null;
-//        List<String> value = new ArrayList<String>();
-//        for (Map.Entry<String, List> entry : map.entrySet()) {
-//            if (CollectionUtils.isEmpty(value)) {
-//                value = entry.getValue();
-//                key = entry.getKey();
-//            } else {
-//                value = entry.getValue();
-//                key = entry.getKey();
-//            }
-//        }
-//        return key;
-//    }
-
-    private String getWXCode(String idcard, String url, String taskName, String taskDesc, String phone, String patientname, String setPatientid, List<String> wxqqxx) {
-        XinHuaWXReq xinHuaWXReq = new XinHuaWXReq();
-        xinHuaWXReq.setIdcard(idcard);
-        xinHuaWXReq.setUrl(url);
-        xinHuaWXReq.setPatientid(setPatientid);
-        xinHuaWXReq.setPatientname(patientname);
-        xinHuaWXReq.setMobile(phone);
-        xinHuaWXReq.setMedcardno(null);
-        xinHuaWXReq.setTitlename(taskName);
-        xinHuaWXReq.setContent(taskDesc);
-        xinHuaWXReq.setAppid(wxqqxx.get(1));
-        log.error("-----寰俊鍏紬鍙风殑鍑哄弬涓�----锛歿}", xinHuaWXReq);
-//         new Gson().toJson(xinHuaWXReq);
-        GsonBuilder gb = new GsonBuilder();
-        gb.disableHtmlEscaping();
-        String body = gb.create().toJson(xinHuaWXReq);
-
-        log.error("encode鐨勫叆鍙備负wxqqxx 锛歿},   body:{}", wxqqxx.get(2), body);
-        String encode = encode(wxqqxx.get(2).concat(body));
-        log.error("--------encode鐨勫�间负锛歿}-----", encode);
-        Map<String, String> headerMap = new HashMap<>();
-        headerMap.put("sign", encode);
-        String result = HttpUtils.sendPostByHeader(wxqqxx.get(3), body, headerMap);
-        log.error("--------result鐨勫�间负锛歿}-----", result);
-
-        JSONObject jsonObject = JSONObject.parseObject(result);
-        String code = (String) jsonObject.toString();
-        return code;
-    }
-
-
-    private String getDXCode(String address, String ShouJiHM, String FaSongNR, String FaSongRID, String FaSongRXM, Map<String, Object> headerMap, String token) {
-        Map<String, Object> map = new LinkedHashMap<>();
-
-        Map<String, Object> YeWuXX = new LinkedHashMap<>();
-        Map<String, Object> DuanXinXX = new LinkedHashMap<>();
-        DuanXinXX.put("ShouJiHM", ShouJiHM);
-        DuanXinXX.put("FaSongNR", FaSongNR);
-        DuanXinXX.put("FaSongRID", FaSongRID);
-        DuanXinXX.put("FaSongRXM", FaSongRXM);
-        YeWuXX.put("DuanXinXX", DuanXinXX);
-
-        map.put("XiaoXiTou", headerMap);
-        map.put("YeWuXX", YeWuXX);
-
-        String body = new Gson().toJson(map);
-
-        String result = null;
-        try {
-            result = OkHttpExample.sendPostRequest(address, body, token);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        log.info("--------result鐨勫�间负锛歿}-----", result);
-
-        JSONObject jsonObject = JSONObject.parseObject(result);
-        String code = (String) jsonObject.toString();
-        return code;
-    }
-
-
-    public String encode(String arg) {
-        if (arg == null) {
-            arg = "";
-        }
-        MessageDigest md5 = null;
-        try {
-            md5 = MessageDigest.getInstance("MD5");
-            md5.update(arg.getBytes("UTF-8"));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        return toHex(md5.digest());
-    }
+    // ---------------------------------------------------------------------
+    // 璇存槑锛氬師 getWXCode / getDXCode / encode 涓変釜绉佹湁鏂规硶宸查殢鍙戦�佹柟涓�璧锋敹鍙e埌
+    // ruoyi-message 妯″潡锛圶inHuaMpApi / LishuiSmsSender锛夛紝姝ゅ宸插垹闄わ紝閬垮厤閲嶅瀹炵幇銆�
+    // 娉ㄦ剰锛氭湰绫荤殑 getWXCode 鍘熶娇鐢� new GsonBuilder().disableHtmlEscaping()锛�
+    //      涓� RyTask.getWXCode 鐨� new Gson() 涓嶅悓锛岃宸紓宸插湪 XinHuaMpApi 涓寜绔欑偣淇濈暀銆�
+    // ---------------------------------------------------------------------
 
     /**
      * 闅忚浠诲姟鏄惁瓒呮椂
@@ -1113,17 +1043,65 @@
         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());
+    }
 }

--
Gitblit v1.9.3