liusheng
2026-10-12 26d1f59f0266672398975ba0337bb3d8267c2d95
ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java
@@ -1,26 +1,25 @@
package com.ruoyi.web.component;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
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.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.HttpUtil;
import com.ruoyi.common.utils.OkHttpExample;
import com.ruoyi.common.utils.RSAPublicKeyExample;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.*;
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.domain.*;
import com.smartor.mapper.HeLibraryMapper;
import com.smartor.mapper.PatArchiveMapper;
import com.smartor.mapper.ServiceSubtaskMapper;
import com.smartor.mapper.ServiceTaskMapper;
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;
@@ -34,14 +33,11 @@
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.security.MessageDigest;
import java.net.URLEncoder;
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;
@Slf4j
@Component//监听此队列
@@ -65,6 +61,7 @@
    @Autowired
    private ServiceSubtaskMapper ivrTaskcallMapper;
    @Autowired
    private HeLibraryMapper heLibraryMapper;
@@ -78,10 +75,13 @@
    private RedisCache redisCache;
    @Autowired
    private ServiceTaskMapper svyTaskMapper;
    private ServiceTaskMapper serviceTaskMapper;
    @Autowired
    private ServiceSubtaskMapper serviceSubtaskMapper;
    @Autowired
    private ServiceSubtaskPreachformMapper serviceSubtaskPreachformMapper;
    @Autowired
    private IServiceSubtaskRecordService serviceSubtaskRecordService;
@@ -89,20 +89,28 @@
    @Autowired
    IBaseSmsaccountService baseSmsaccountService;
    @Autowired
    private ISysConfigService configService;
    @Value("${xhsmsPath}")
    private String xhsmsPath;
    @Value("${visitHosp}")
    private Integer visitHosp;
    @Value("${server.port}")
    private String port;
    // 创建固定大小的线程池
    private static final ExecutorService executorService = Executors.newFixedThreadPool(10);
    /**
     * 消息发送方工厂(短信/微信公众号)。
     * <p>
     * 原来短信与公众号的发送逻辑在本类里用 {@code if (active.equals("xx"))} 硬分支了约 300 行,
     * 现已收口到 {@code ruoyi-message} 模块,这里只负责按 {@code active} 路由。
     */
    @Autowired
    private SmsSenderFactory smsSenderFactory;
    @Autowired
    private WechatSenderFactory wechatSenderFactory;
    @Value("${spring.profiles.active}")
    private String active;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    public RedisMqReceiver(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
@@ -134,9 +142,13 @@
            //将状态改成完成
            ServiceTask serviceTask = new ServiceTask();
            serviceTask.setTaskid(Long.valueOf(commonTaskcallMQ.getTaskid()));
            serviceTask.setSendState(5L);
            serviceTask.setFail(1L);
            svyTaskMapper.updateServiceTask(serviceTask);
//            //在问卷中,选中某个选项要进行服务补偿时,只是借用该服务的外壳,不对该服务有任务影响
//            if (commonTaskcallMQ.getUpdateSendstate() == null || commonTaskcallMQ.getUpdateSendstate() == 1) {
//                serviceTask.setSendState(5L);
//                serviceTask.setFail(1L);
//                serviceTaskMapper.updateServiceTask(serviceTask);
//            }
        } catch (Exception e) {
            Integer integer = redisCache.getCacheObject(commonTaskcallMQ.getTaskid().toString());
            if (integer != null && integer == 3) {
@@ -144,7 +156,7 @@
                ServiceTask serviceTask = new ServiceTask();
                serviceTask.setTaskid(Long.valueOf(commonTaskcallMQ.getTaskid().toString()));
                serviceTask.setFail(0L);
                svyTaskMapper.updateServiceTask(serviceTask);
                serviceTaskMapper.updateServiceTask(serviceTask);
                //将消息从队列中删除
            } else if (integer == null) {
                redisCache.setCacheObject(commonTaskcallMQ.getTaskid().toString(), 1, 120, TimeUnit.MINUTES);
@@ -157,7 +169,7 @@
    }
    /**
     * 任务处理
     * 任务处理 单次随访
     *
     * @param commonTaskcallMQ
     */
@@ -166,609 +178,751 @@
        //判断一下commonTaskcallMQ中的stopstate是否与ivr_task中的一致,不一致,则说明是暂停了
        ServiceTask ivrTask1 = ivrTaskMapper.selectServiceTaskByTaskid(commonTaskcallMQ.getTaskid());
//        if (ivrTask1.getStopState() != commonTaskcallMQ.getStopState()) {
//            //将消息从队列中剔除
//            return;
//        }
        //通过任务ID拿到患者信息
        ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity();
        serviceSubtaskVO.setTaskid(commonTaskcallMQ.getTaskid());
        serviceSubtaskVO.setSendstate(2L);
        List<ServiceSubtask> selectServiceSubtaskList = ivrTaskcallMapper.selectServiceSubtaskList(serviceSubtaskVO);
        if (StringUtils.isNotEmpty(commonTaskcallMQ.getPreachform())) {
            //如何任务发送方式不为空
            String[] split = commonTaskcallMQ.getPreachform().split(",");
            log.info("split的值为:{}", split);
        for (ServiceSubtask serviceSubtask : selectServiceSubtaskList) {
            //先判断患者是不是还要发送
            PatArchive patArchive = patArchiveMapper.selectPatArchiveByPatid(serviceSubtask.getPatid());
            if (!Objects.isNull(patArchive) && patArchive.getNotrequiredFlag() == "1") {
                //不需要发送
                serviceSubtask.setResult("患者不需要随访");
                serviceSubtask.setRemark(patArchive.getNotrequiredreason());
                serviceSubtask.setSendstate(4L);
                serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                setFailPreachForm(serviceSubtask, "-1", "不需要执行", "6");
                continue;
            }
            //定义一个集合,用与存没有执行的子任务ID
            List<Long> subIds = new ArrayList<>();
            //临时存没有执行的子任务ID
            List<Long> lssubIds = new ArrayList<>();
            //是否将全部患者者发送完
            Boolean isSend = false;
            ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
            serviceSubtaskPreachform.setTaskid(serviceSubtask.getTaskid());
            serviceSubtaskPreachform.setSubid(serviceSubtask.getId());
            //获取发送方式
            String sendPreachform = getSendPreachform(serviceSubtaskPreachform, serviceSubtask);
            log.info("sendPreachform的值为:{}", sendPreachform);
            if (sendPreachform.equals("-1") || serviceSubtask.getSendstate() == 6 || serviceSubtask.getSendstate() == 5 || serviceSubtask.getSendstate() == 4) {
                //说明已经全部遍历完了,当前的执行方式序号是最后一个了   或者  该患者已经随访结束(成功或失败了或不执行)
                continue;
            }
            String descByCode = ServiceFromEnum.getDescByCode(Integer.valueOf(sendPreachform));
            if (descByCode.equals("电话")) {
                try {
                    ServiceTask ivrTask = ivrTaskMapper.selectServiceTaskByTaskid(serviceSubtask.getTaskid());
                    if (ivrTask.getSendState() != null && ivrTask.getSendState() == 3 || ivrTask.getSendState() != null && ivrTask.getSendState() == 4) {
                        //如何任务被“暂停”或“终止”
                        break;
                    }
                    if (org.apache.commons.lang3.StringUtils.isEmpty(serviceSubtask.getPhone())) {
                        serviceSubtask.setCurrentPreachform(sendPreachform);
                        serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime(), serviceSubtask.getCurrentPreachform()));
                        serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                        setFailPreachForm(serviceSubtask, sendPreachform, "手机号为空", "4");
                        continue;
                    }
            aa:
            for (String serviceFrom : split) {
                String descByCode = ServiceFromEnum.getDescByCode(Integer.valueOf(serviceFrom));
                if (isSend == true) {
                    break aa;
                }
                    //获取到value值最少的key
                    String key = getKey();
                    if (commonTaskcallMQ.getSendType().equals("2")) {
                        //说明是立即发送
                        List<String> list = new ArrayList<>();
                        list.add(serviceSubtask.getId().toString());
                        log.info("缓存中cache-0的值为:{}", list);
                        redisCache.setCacheListLeftAndDistinct("cache-0", list);
                    } else {
                        //非立即发送
                        List<String> list = new ArrayList<>();
                        list.add(serviceSubtask.getId().toString());
                        redisCache.setCacheListLeftAndDistinct(key, list);
                    }
                } catch (Exception exception) {
                    ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                    serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
                    serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
                    serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
                    serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
                    serviceSubtaskRecord.setPreachform("3");
                    serviceSubtaskRecord.setResult("fail");
                    serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
                    serviceSubtaskRecord.setRemark("队列任务电话发送失败");
                    log.error("队列任务电话发送失败:{}", exception.getMessage());
                    serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
                    //将电话状态设置为失败
                    setFailPreachForm(serviceSubtask, sendPreachform, "队列任务电话发送失败", "5");
                //通过任务ID拿到患者信息
                ServiceSubtaskVO ivrTaskcall = new ServiceSubtaskVO();
                ivrTaskcall.setTaskid(commonTaskcallMQ.getTaskid());
                ivrTaskcall.setSendstate(1L);
                List<ServiceSubtask> selectServiceSubtaskList = ivrTaskcallMapper.selectServiceSubtaskList(ivrTaskcall);
                if (CollectionUtils.isEmpty(selectServiceSubtaskList)) {
                    continue;
                }
                if (descByCode.equals("电话")) {
                    for (ServiceSubtask serviceSubtask : selectServiceSubtaskList) {
                        //先判断一下,subIds是否为空,如果不为空,只执行subIds里的患者
                        if (CollectionUtils.isNotEmpty(subIds)) {
                            boolean contains = subIds.contains(serviceSubtask.getId());
                            //如果contains不为true,说明当前的患者已经发送成功,直接循环下一个人就行
                            if (!contains) continue;
                //在子任务表里记录一下
                setFailPreachForm(serviceSubtask, sendPreachform, "队列任务电话发送成功", "2");
                //任务发送记录
                ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
                serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
                serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
                serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
                serviceSubtaskRecord.setPreachform("3");
                serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
                serviceSubtaskRecord.setRemark("队列任务电话发送成功");
                serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
            } else if (descByCode.equals("短信")) {
                log.info("----active的值为:{}", active);
                //短信
                //对url中两个参数加密
                RSAPublicKeyExample rsaPublicKeyExample = new RSAPublicKeyExample();
                String taskId = rsaPublicKeyExample.encryptedData(ivrTask1.getTaskid().toString(), pub_key);
                if (org.apache.commons.lang3.StringUtils.isEmpty(serviceSubtask.getPhone())) {
                    setFailPreachForm(serviceSubtask, sendPreachform, "手机号为空", "4");
                    continue;
                }
                try {
                    String patid = rsaPublicKeyExample.encryptedData(serviceSubtask.getPatid().toString(), pub_key);
                    String subId = rsaPublicKeyExample.encryptedData(serviceSubtask.getId().toString(), pub_key);
                    SendMagParam sendMagParam = new SendMagParam();
                    sendMagParam.setType("4");
                    if (type == 1) {
                        //随访
                        ServiceOutPath serviceOutPath = new ServiceOutPath();
                        serviceOutPath.setParam1(taskId);
                        serviceOutPath.setParam2(patid);
                        serviceOutPath.setParam6(subId);
                        serviceOutPath.setCreateTime(new Date());
                        serviceOutPath.setOrgid(serviceSubtask.getOrgid());
                        serviceOutPath.setDeptCode(serviceSubtask.getDeptcode());
                        serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode());
                        serviceOutPath.setDeptName(serviceSubtask.getDeptname());
                        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());
                        serviceOutPath.setRadix(format);
                        serviceOutPath.setUpdateTime(new Date());
                        serviceOutPath.setUrl(ip + ":" + req_path + "/sf?p=" + format);
                        iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                        sendMagParam.setPhone(serviceSubtask.getPhone());
                        sendMagParam.setUrl(ip + ":" + req_path + "/sf?p=" + format);
                        SysConfig sysConfig = new SysConfig();
                        if (StringUtils.isNotEmpty(serviceSubtask.getServiceType()) && serviceSubtask.getServiceType().equals("6")) {
                            sysConfig = sysConfigMapper.checkConfigKeyUnique("zymyd.sms.template");
                        } else if (StringUtils.isNotEmpty(serviceSubtask.getServiceType()) && serviceSubtask.getServiceType().equals("14")) {
                            sysConfig = sysConfigMapper.checkConfigKeyUnique("mzmyd.sms.template");
                        } else {
                            sysConfig = sysConfigMapper.checkConfigKeyUnique("wj.sms.template");
                        }
                        if (!Objects.isNull(sysConfig)) {
                            String smsContemt = sysConfig.getConfigValue();
//                          sendMagParam.setContent("您好,邀请您填写出院随访调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
                            sendMagParam.setContent(smsContemt.replace("${wjurl}", sendMagParam.getUrl()));
                        }
                        try {
                            ServiceTask ivrTask = ivrTaskMapper.selectServiceTaskByTaskid(serviceSubtask.getTaskid());
                            if (ivrTask.getSendState() != null && ivrTask.getSendState() == 3 || ivrTask.getSendState() != null && ivrTask.getSendState() == 4) {
                                //如何任务被“暂停”或“终止”
                                break;
                            }
                            //获取到value值最少的key
                            String key = getKey();
                            if (commonTaskcallMQ.getSendType().equals("2")) {
                                //说明是立即发送
                                ServiceSubtaskVO serviceSubtask1 = new ServiceSubtaskVO();
                                serviceSubtask1.setTaskid(commonTaskcallMQ.getTaskid());
                                log.info("缓存中serviceSubtask1的值为:{}", serviceSubtask1);
                                List<String> list = new ArrayList<>();
                                List<ServiceSubtask> selectServiceSubtaskList1 = ivrTaskcallMapper.selectServiceSubtaskList(serviceSubtask1);
                                for (ServiceSubtask serviceSubtask2 : selectServiceSubtaskList1) {
                                    list.add(serviceSubtask2.getId().toString());
                                }
                                log.info("缓存中cache-0的值为:{}", list);
//                                redisCache.setCacheListLeft("cache-0", list);
                                redisCache.setCacheListLeftAndDistinct("cache-0", list);
                            } else {
                                //非立即发送
                                ServiceSubtaskVO serviceSubtask1 = new ServiceSubtaskVO();
                                serviceSubtask1.setTaskid(commonTaskcallMQ.getTaskid());
                                List<ServiceSubtask> selectServiceSubtaskList1 = ivrTaskcallMapper.selectServiceSubtaskList(serviceSubtask1);
                                List<String> list = new ArrayList<>();
                                for (ServiceSubtask serviceSubtask2 : selectServiceSubtaskList1) {
                                    list.add(serviceSubtask2.getId().toString());
                                }
//                                redisCache.setCacheListLeft(key, list);
                                redisCache.setCacheListLeftAndDistinct(key, list);
                            }
                        } catch (Exception exception) {
                            ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                            serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
                            serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
                            serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
                            serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
                            serviceSubtaskRecord.setPreachform("3");
                            serviceSubtaskRecord.setResult("fail");
                            serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
                            serviceSubtaskRecord.setRemark("队列任务电话发送失败");
                            log.error("队列任务电话发送失败:{}", exception.getMessage());
                            lssubIds.add(serviceSubtask.getId());
                            serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
                            continue;
                    } else if (type == 2) {
                        //问券(问题)
                        ServiceOutPath serviceOutPath = new ServiceOutPath();
                        serviceOutPath.setParam1(taskId);
                        serviceOutPath.setParam2(patid);
                        serviceOutPath.setParam6(subId);
//                                serviceOutPath.setParam3(URLEncoder.encode(ivrTask1.getTaskName(), StandardCharsets.UTF_8.toString()));
                        serviceOutPath.setParam3(ivrTask1.getTaskName());
                        serviceOutPath.setCreateTime(new Date());
                        serviceOutPath.setOrgid(serviceSubtask.getOrgid());
                        serviceOutPath.setDeptCode(serviceSubtask.getDeptcode());
                        serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode());
                        serviceOutPath.setDeptName(serviceSubtask.getDeptname());
                        serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname());
                        iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                        String format = String.format("%03X", 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);
                        iServiceOutPathService.updateServiceOutPath(serviceOutPath);
//                                sendMagParam.setUrl(ip + ":" + req_path + "/outsideChainwt?param1=" + taskId + "&param2=" + patid + "&param3=" + URLEncoder.encode(ivrTask1.getTaskName(), StandardCharsets.UTF_8.toString()) + "&param5=false");
                        sendMagParam.setPhone(serviceSubtask.getPhone());
                        sendMagParam.setUrl(StringUtils.isNotEmpty(req_path) ? ip + ":" + req_path + "/wt?p=" + format : ip + "/wt?p=" + format);
                        log.info("sendMagParam的值为:{}", sendMagParam);
                        //如果type是语音随访的话(说明补偿发送方式中有电话随访的方式,这里的外链就地址只能用/sf)
                        if (serviceSubtask.getType().equals("1"))
                            sendMagParam.setUrl(StringUtils.isNotEmpty(req_path) ? ip + ":" + req_path + "/sf?p=" + format : ip + "/sf?p=" + format);
                        SysConfig sysConfig = new SysConfig();
                        if (StringUtils.isNotEmpty(serviceSubtask.getServiceType()) && serviceSubtask.getServiceType().equals("6")) {
                            sysConfig = sysConfigMapper.checkConfigKeyUnique("zymyd.sms.template");
                        } else if (StringUtils.isNotEmpty(serviceSubtask.getServiceType()) && serviceSubtask.getServiceType().equals("14")) {
                            sysConfig = sysConfigMapper.checkConfigKeyUnique("mzmyd.sms.template");
                        } else {
                            sysConfig = sysConfigMapper.checkConfigKeyUnique("wj.sms.template");
                        }
                        if (!Objects.isNull(sysConfig)) {
                            String smsContemt = sysConfig.getConfigValue();
//                          sendMagParam.setContent("您好,邀请您填写出院随访调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
                            sendMagParam.setContent(smsContemt.replace("${wjurl}", sendMagParam.getUrl()));
                        }
                    } else if (type == 3) {
                        //宣教
                        ServiceOutPath serviceOutPath = new ServiceOutPath();
                        serviceOutPath.setParam1(taskId);
                        serviceOutPath.setParam2(patid);
                        serviceOutPath.setParam6(subId);
                        serviceOutPath.setParam3(ivrTask1.getTaskName());
                        serviceOutPath.setCreateTime(new Date());
                        serviceOutPath.setOrgid(serviceSubtask.getOrgid());
                        serviceOutPath.setDeptCode(serviceSubtask.getDeptcode());
                        serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode());
                        serviceOutPath.setDeptName(serviceSubtask.getDeptname());
                        serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname());
                        iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                        String url = "";
                        String format = String.format("%03X", serviceOutPath.getId());
                        //需要通过模板ID去判断要发的内容是宣教还是通知
                        HeLibrary heLibrary = heLibraryMapper.selectHeLibraryById(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;
                            sendMagParam.setUrl(url);
                            SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique("xj.sms.template");
                            if (!Objects.isNull(sysConfig)) {
                                String smsContemt = sysConfig.getConfigValue();
//                              sendMagParam.setContent("您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
                                sendMagParam.setContent(smsContemt.replace("${xjurl}", sendMagParam.getUrl()));
                            }
//                            if (active.equals("ls") || active.equals("sltd") || active.equals("nhfy")) {
//                                sendMagParam.setContent("您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
//                            } else if (active.equals("xh")) {
//                                sendMagParam.setContent("【新华医院】您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
//                            } else if (active.equals("hzszlyy")) {
//                                sendMagParam.setContent("【杭州市第一人民医院】您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "填写。感谢您配合!");
//                            }
                        } else if (heLibrary.getHetype().equals("2")) {
                            //通知
                            String sc = getSC(serviceSubtask, heLibrary.getPreachcontent());
                            sendMagParam.setPhone(serviceSubtask.getPhone());
                            sendMagParam.setContent(sc);
                        }
                        serviceOutPath.setRadix(format);
                        serviceOutPath.setUpdateTime(new Date());
                        serviceOutPath.setUrl(url);
                        iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                    }
                    //短信发送:各站点对接方式差异较大(报文/签名/token/返回判定都不同),
                    //已收口到 ruoyi-message 模块,这里只负责组装入参并路由
                    log.info("----active的值为:{}", active);
                    SendResult smsSendResult = sendSmsByActive(serviceSubtask, sendMagParam);
                    if (smsSendResult.isOk()) {
                        //在子任务表里记录一下
                        String uuid = UUID.randomUUID().toString();
                        serviceSubtask.setResult("success");
                        serviceSubtask.setRemark("队列任务电话发送成功");
                        serviceSubtask.setGuid(uuid);
                        serviceSubtask.setSendstate(3L);
                        serviceSubtask.setFinishtime(new Date());
                        serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                        setFailPreachForm(serviceSubtask, sendPreachform, "短信发送成功", "2");
                        //任务发送记录
                        ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                        serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
                        serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
                        serviceSubtaskRecord.setUuid(uuid);
                        serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
                        serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
                        serviceSubtaskRecord.setPreachform("3");
                        serviceSubtaskRecord.setPreachform("5");
                        serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
                        serviceSubtaskRecord.setRemark("队列任务电话发送成功");
                        serviceSubtaskRecord.setResult("success");
                        serviceSubtaskRecord.setRemark("短信发送成功");
                        serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
                    } else {
                        //在子任务表里记录一下
                        setFailPreachForm(serviceSubtask, sendPreachform, "短信发送失败", "5");
                        continue;
                    }
                    if (CollectionUtils.isEmpty(lssubIds)) {
                        //如果“临时子任务”为空,说明全发送完了
                        isSend = true;
                    }
                    //将子任务ID清空,将“临时子任务”数据 放到 “子任务” 中
                    subIds.clear();
                    subIds.addAll(lssubIds);
                    lssubIds.clear();
                } else if (descByCode.equals("多媒体")) {
                    //多媒体
                } catch (Exception e) {
                    ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                    serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
                    serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
                    serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
                    serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
                    serviceSubtaskRecord.setPreachform("4");
                    serviceSubtaskRecord.setResult("fail");
                    serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
                    serviceSubtaskRecord.setRemark("短信发送失败");
                    log.error("短信发送失败:{}", e.getMessage());
                    serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
                    setFailPreachForm(serviceSubtask, sendPreachform, "短信发送失败", "5");
                    continue;
                } else if (descByCode.equals("纸质")) {
                    //纸质
                    continue;
                } else if (descByCode.equals("短信")) {
                    //短信
                    //对url中两个参数加密
                    RSAPublicKeyExample rsaPublicKeyExample = new RSAPublicKeyExample();
                    String taskId = rsaPublicKeyExample.encryptedData(ivrTask1.getTaskid().toString(), pub_key);
                }
                    for (ServiceSubtask serviceSubtask : selectServiceSubtaskList) {
                        //先判断一下,subIds是否为空,如果不为空,只执行subIds里的患者
                        if (CollectionUtils.isNotEmpty(subIds)) {
                            boolean contains = subIds.contains(serviceSubtask.getId());
                            //如果contains不为true,说明当前的患者已经发送成功,直接循环下一个人就行
                            if (!contains) continue;
                        }
            } else if (descByCode.equals("公众号")) {
                //公众号
                RSAPublicKeyExample rsaPublicKeyExample = new RSAPublicKeyExample();
                String taskId = rsaPublicKeyExample.encryptedData(ivrTask1.getTaskid().toString(), pub_key);
                String patid = rsaPublicKeyExample.encryptedData(serviceSubtask.getPatid().toString(), pub_key);
                String subId = rsaPublicKeyExample.encryptedData(serviceSubtask.getId().toString(), pub_key);
                try {
                    SendMagParam sendMagParam = new SendMagParam();
                    sendMagParam.setType("5");
                    String url = null;
                    Boolean aBoolean = false;
                    if (type == 1) {
                        //随访
                        ServiceOutPath serviceOutPath = new ServiceOutPath();
                        serviceOutPath.setParam1(taskId);
                        serviceOutPath.setParam2(patid);
                        serviceOutPath.setParam6(subId);
                        serviceOutPath.setCreateTime(new Date());
                        serviceOutPath.setOrgid(serviceSubtask.getOrgid());
                        serviceOutPath.setDeptCode(serviceSubtask.getDeptcode());
                        serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode());
                        serviceOutPath.setDeptName(serviceSubtask.getDeptname());
                        serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname());
                        iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                        String format = String.format("%03X", serviceOutPath.getId());
                        serviceOutPath.setRadix(format);
                        serviceOutPath.setUpdateTime(new Date());
                        url = ip + ":" + req_path + "/sf?p=" + format;
                        serviceOutPath.setUrl(url);
                        iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                    } else if (type == 2) {
                        //问券
                        ServiceOutPath serviceOutPath = new ServiceOutPath();
                        serviceOutPath.setParam1(taskId);
                        serviceOutPath.setParam2(patid);
                        serviceOutPath.setParam3(ivrTask1.getTaskName());
                        serviceOutPath.setParam6(subId);
                        serviceOutPath.setCreateTime(new Date());
                        serviceOutPath.setOrgid(serviceSubtask.getOrgid());
                        serviceOutPath.setDeptCode(serviceSubtask.getDeptcode());
                        serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode());
                        serviceOutPath.setDeptName(serviceSubtask.getDeptname());
                        serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname());
                        iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                        String format = String.format("%03X", serviceOutPath.getId());
                        try {
                            String patid = rsaPublicKeyExample.encryptedData(serviceSubtask.getPatid().toString(), pub_key);
                            String subId = rsaPublicKeyExample.encryptedData(serviceSubtask.getId().toString(), pub_key);
                            SendMagParam sendMagParam = new SendMagParam();
                            sendMagParam.setType("4");
                            if (type == 1) {
                                //随访
                                ServiceOutPath serviceOutPath = new ServiceOutPath();
                                serviceOutPath.setParam1(taskId);
                                serviceOutPath.setParam2(patid);
                                serviceOutPath.setParam6(subId);
                                serviceOutPath.setCreateTime(new Date());
                                iServiceOutPathService.insertServiceOutPath(serviceOutPath);
//                                sendMagParam.setUrl(ip + ":" + req_path + "/followvisit/particty?param1=" + taskId + "&param2=" + patid + "&param5=false");
                                //转成16进制
                                String format = String.format("%03X", serviceOutPath.getId());
                                serviceOutPath.setRadix(format);
                                serviceOutPath.setUpdateTime(new Date());
                                iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                                sendMagParam.setPhone(serviceSubtask.getPhone());
                                sendMagParam.setUrl(ip + ":" + req_path + "/sf?p=" + format);
                                if (visitHosp == 2) {
                                    sendMagParam.setContent("您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
                                } else if (visitHosp == 1) {
                                    sendMagParam.setContent("【新华医院】您好,邀请您填写出院随访调查表,请点击" + sendMagParam.getUrl() + "填写。感谢您配合!");
                                }
                        url = StringUtils.isNotEmpty(req_path) ? ip + ":" + req_path + "/wt?p=" + format : ip + "/wt?p=" + format;
                        //如果type是语音随访的话(说明补偿发送方式中有电话随访的方式,这里的外链就地址只能用/sf)
                        if (serviceSubtask.getType().equals("1"))
                            sendMagParam.setUrl(ip + ":" + req_path + "/sf?p=" + format);
                            } else if (type == 2) {
                                //问券(问题)
                                ServiceOutPath serviceOutPath = new ServiceOutPath();
                                serviceOutPath.setParam1(taskId);
                                serviceOutPath.setParam2(patid);
                                serviceOutPath.setParam6(subId);
//                                serviceOutPath.setParam3(URLEncoder.encode(ivrTask1.getTaskName(), StandardCharsets.UTF_8.toString()));
                                serviceOutPath.setParam3(ivrTask1.getTaskName());
                                serviceOutPath.setCreateTime(new Date());
                                iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                                String format = String.format("%03X", serviceOutPath.getId());
                                serviceOutPath.setRadix(format);
                                serviceOutPath.setUpdateTime(new Date());
                                iServiceOutPathService.updateServiceOutPath(serviceOutPath);
//                                sendMagParam.setUrl(ip + ":" + req_path + "/outsideChainwt?param1=" + taskId + "&param2=" + patid + "&param3=" + URLEncoder.encode(ivrTask1.getTaskName(), StandardCharsets.UTF_8.toString()) + "&param5=false");
                                sendMagParam.setPhone(serviceSubtask.getPhone());
                                sendMagParam.setUrl(ip + ":" + req_path + "/wt?p=" + format);
                                if (serviceSubtask.getOrgid().equals("47255004333112711A1001")) {
                                    sendMagParam.setContent("【景宁畲族自治县人民医院】您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
                                } else if (serviceSubtask.getOrgid().equals("47255004333112711A1001")) {
                                    sendMagParam.setContent("【丽水中医院】您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
                                } else
                                    sendMagParam.setContent("【新华医院】您好,邀请您填写出院调查表,请点击" + sendMagParam.getUrl() + "填写。感谢您配合!");
                            } else if (type == 3) {
                                //宣教
                                ServiceOutPath serviceOutPath = new ServiceOutPath();
                                serviceOutPath.setParam1(taskId);
                                serviceOutPath.setParam2(patid);
                                serviceOutPath.setParam6(subId);
                                serviceOutPath.setParam3(ivrTask1.getTaskName());
                                serviceOutPath.setCreateTime(new Date());
                                iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                                String format = String.format("%03X", serviceOutPath.getId());
                                serviceOutPath.setRadix(format);
                                serviceOutPath.setUpdateTime(new Date());
                                iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                                //需要通过模板ID去判断要发的内容是宣教还是通知
                                HeLibrary heLibrary = heLibraryMapper.selectHeLibraryById(serviceSubtask.getLibtemplateid());
                                if (heLibrary.getHetype().equals("1")) {
                                    sendMagParam.setPhone(serviceSubtask.getPhone());
                                    sendMagParam.setUrl(ip + ":" + req_path + "/xj?p=" + format);
                                    if (serviceSubtask.getOrgid().equals("47255004333112711A1001")) {
                                        sendMagParam.setContent("【景宁畲族自治县人民医院】您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
                                    } else if (serviceSubtask.getOrgid().equals("47255004333112711A1001")) {
                                        sendMagParam.setContent("【丽水中医院】您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
                                    } else
                                        sendMagParam.setContent("【新华医院】您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
                                } else {
                                    //通知
                                    sendMagParam.setPhone(serviceSubtask.getPhone());
                                    sendMagParam.setContent(heLibrary.getPreachcontent());
                                }
                            }
                            //短信还需要模板
                            String s = null;
                            if (visitHosp == 1) {
                                //新华的短信发送方式
                                Map<String, String> req = new HashMap<>();
                                req.put("phone", sendMagParam.getPhone());
                                req.put("content", sendMagParam.getContent());
                                s = HttpUtil.postJsonRequest(xhsmsPath, new Gson().toJson(req));
                            } else if (visitHosp == 2) {
                                String url = configService.selectConfigByKey("token.360",serviceSubtask.getOrgid());
                                //丽水的短信发送方式
                                Map<String, String> map = MsgLSEnum.getAddressByCode(serviceSubtask.getOrgid());
                                String token = LSHospTokenUtil.getToken(serviceSubtask.getOrgid(),url);
                                log.info("-----------token的值为:{}", token);
                                if (ObjectUtils.isNotEmpty(map) && StringUtils.isEmpty(map.get("address"))) {
                                    ServiceSubtask ss = new ServiceSubtask();
                                    ss.setResult("error");
                                    ss.setRemark("短信发送失败,该机构没有配置短信地址");
                                    ss.setSendstate(5L);
                                    ss.setId(serviceSubtask.getId());
//                                    ss.setFinishtime(new Date());
                                    serviceSubtaskMapper.updateServiceSubtask(ss);
                                    continue;
                                }
                                log.info("---------mq丽水短信发送入参address:{},  sendMagParam:{},  orgid:{}-------", map.get("address"), sendMagParam, serviceSubtask.getOrgid());
                                String dxCode = getDXCode(map.get("address"), sendMagParam.getPhone(), sendMagParam.getContent(), map.get("sendPersonId"), map.get("sendPersonName"), MsgLSEnum.getHeaderByCode(serviceSubtask.getOrgid()), token);
                                log.info("---------丽水短信发送结果:{}-------", dxCode);
                                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 {
                                    throw new BaseException(null);
                                }
                            }
                            if (s.equals("true")) {
                                //在子任务表里记录一下
                                String uuid = UUID.randomUUID().toString();
                                serviceSubtask.setResult("success");
                                serviceSubtask.setRemark("短信发送成功");
                                serviceSubtask.setGuid(uuid);
                                serviceSubtask.setSendstate(3L);
                                serviceSubtask.setFinishtime(new Date());
                                serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                        serviceOutPath.setRadix(format);
                        serviceOutPath.setUrl(url);
                        serviceOutPath.setUpdateTime(new Date());
                        iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                    } else if (type == 3) {
                        //宣教
                        ServiceOutPath serviceOutPath = new ServiceOutPath();
                        serviceOutPath.setParam1(taskId);
                        serviceOutPath.setParam2(patid);
                        serviceOutPath.setParam3(ivrTask1.getTaskName());
                        serviceOutPath.setParam6(subId);
                        serviceOutPath.setCreateTime(new Date());
                        serviceOutPath.setDeptCode(serviceSubtask.getDeptcode());
                        serviceOutPath.setWardCode(serviceSubtask.getLeavehospitaldistrictcode());
                        serviceOutPath.setDeptName(serviceSubtask.getDeptname());
                        serviceOutPath.setWardName(serviceSubtask.getLeavehospitaldistrictname());
                        serviceOutPath.setOrgid(serviceSubtask.getOrgid());
                        iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                        String format = String.format("%03X", serviceOutPath.getId());
                                //任务发送记录
                                ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                                serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
                                serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
                                serviceSubtaskRecord.setUuid(uuid);
                                serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
                                serviceSubtaskRecord.setPreachform("5");
                                serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
                                serviceSubtaskRecord.setResult("success");
                                serviceSubtaskRecord.setRemark("短信发送成功");
                                serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
                                log.error("serviceSubtaskRecord保存成功了吗?:{}", serviceSubtaskRecord);
                            }
                        } catch (Exception e) {
                            ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                            serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
                            serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
                            serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
                            serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
                            serviceSubtaskRecord.setPreachform("4");
                            serviceSubtaskRecord.setResult("fail");
                            serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
                            serviceSubtaskRecord.setRemark("短信发送失败");
                            log.error("短信发送失败:{}", e.getMessage());
                            lssubIds.add(serviceSubtask.getId());
                            serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
                            continue;
                        }
                        //需要通过模板ID去判断要发的内容是宣教还是通知
//                        HeLibrary heLibrary = heLibraryMapper.selectHeLibraryById(serviceSubtask.getLibtemplateid());
//                        if (heLibrary.getHetype().equals("1")) {
//                            sendMagParam.setPhone(serviceSubtask.getPhone());
//                            sendMagParam.setUrl(ip + ":" + req_path + "/xj?p=" + format);
//                            if (active.equals("ls") || active.equals("sltd")) {
//                                sendMagParam.setContent("您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
//                            } else if (active.equals("xh")) {
//                                sendMagParam.setContent("【新华医院】您好,邀请您填写出院宣教调查表,请点击" + sendMagParam.getUrl() + "查看。感谢您配合!");
//                            }
//                        } else if (heLibrary.getHetype().equals("2")) {
//                            //通知
//                            String sc = getSC(serviceSubtask, heLibrary.getPreachcontent());
//                            sendMagParam.setPhone(serviceSubtask.getPhone());
//                            sendMagParam.setContent(sc);
//                        }
                        url = ip + ":" + req_path + "/xj?p=" + format;
                        serviceOutPath.setRadix(format);
                        serviceOutPath.setUpdateTime(new Date());
                        serviceOutPath.setUrl(url);
                        iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                    }
                    if (CollectionUtils.isEmpty(lssubIds)) {
                        //如果“临时子任务”为空,说明全发送完了
                        isSend = true;
                    }
                    //将子任务ID清空,将“临时子任务”数据 放到 “子任务” 中
                    subIds.clear();
                    subIds.addAll(lssubIds);
                    lssubIds.clear();
                } else if (descByCode.equals("公众号")) {
                    //公众号
                    RSAPublicKeyExample rsaPublicKeyExample = new RSAPublicKeyExample();
                    String taskId = rsaPublicKeyExample.encryptedData(ivrTask1.getTaskid().toString(), pub_key);
                    for (ServiceSubtask serviceSubtask : selectServiceSubtaskList) {
                        String patid = rsaPublicKeyExample.encryptedData(serviceSubtask.getPatid().toString(), pub_key);
                        try {
                            SendMagParam sendMagParam = new SendMagParam();
                            sendMagParam.setType("5");
                            String url = null;
                            Boolean aBoolean = false;
                            if (type == 1) {
                                //随访
                                ServiceOutPath serviceOutPath = new ServiceOutPath();
                                serviceOutPath.setParam1(taskId);
                                serviceOutPath.setParam2(patid);
                                serviceOutPath.setCreateTime(new Date());
                                iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                                String format = String.format("%03X", serviceOutPath.getId());
                                serviceOutPath.setRadix(format);
                                serviceOutPath.setUpdateTime(new Date());
                                iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                                url = ip + ":" + req_path + "/sf?p=" + format;
                            } else if (type == 2) {
                                //问券
                                ServiceOutPath serviceOutPath = new ServiceOutPath();
                                serviceOutPath.setParam1(taskId);
                                serviceOutPath.setParam2(patid);
//                                serviceOutPath.setParam3(URLEncoder.encode(ivrTask1.getTaskName(), StandardCharsets.UTF_8.toString()));
                                serviceOutPath.setParam3(ivrTask1.getTaskName());
                                serviceOutPath.setCreateTime(new Date());
                                iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                                String format = String.format("%03X", serviceOutPath.getId());
                                serviceOutPath.setRadix(format);
                                serviceOutPath.setUpdateTime(new Date());
                                iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                                url = ip + ":" + req_path + "/wt?p=" + format;
                            } else if (type == 3) {
                                //宣教
                                ServiceOutPath serviceOutPath = new ServiceOutPath();
                                serviceOutPath.setParam1(taskId);
                                serviceOutPath.setParam2(patid);
                                serviceOutPath.setParam3(ivrTask1.getTaskName());
                                serviceOutPath.setCreateTime(new Date());
                                iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                                String format = String.format("%03X", serviceOutPath.getId());
                                serviceOutPath.setRadix(format);
                                serviceOutPath.setUpdateTime(new Date());
                                iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                                url = ip + ":" + req_path + "/xj?p=" + format;
                            }
                            PatArchive patArchive = patArchiveMapper.selectPatArchiveByPatid(serviceSubtask.getPatid());
                            if (StringUtils.isEmpty(patArchive.getPatidHis())) {
                                ServiceSubtask ss = new ServiceSubtask();
                                ss.setResult("error");
                                ss.setRemark("公众号发送失败,his系统的患者id为空");
                                ss.setSendstate(5L);
                                ss.setId(serviceSubtask.getId());
//                                ss.setFinishtime(new Date());
                                serviceSubtaskMapper.updateServiceSubtask(ss);
                                continue;
                            }
                            //获取微信公众号请求信息根据机构ID
                            log.error("获取微信公众号请求信息根据机构ID:{}", patArchive.getOrgid());
                            List<String> wxqqxx = WxGZHEnum.getDescByCode(patArchive.getOrgid());
                            if (CollectionUtils.isEmpty(wxqqxx) || wxqqxx.size() < 4) {
                                ServiceSubtask ss = new ServiceSubtask();
                                ss.setResult("error");
                                ss.setRemark("该机构的公众号配置信息不全,无法通过公众号发送");
                                ss.setSendstate(5L);
                                ss.setId(serviceSubtask.getId());
//                                ss.setFinishtime(new Date());
                                serviceSubtaskMapper.updateServiceSubtask(ss);
                                continue;
                            }
                            String 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);
                                    lssubIds.add(serviceSubtask.getId());
                                    serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
                                    continue;
                                }
                            }
                        } catch (Exception e) {
                    //机构配置校验(WxGZHEnum)与 his 患者id 校验已收口到
                    //ruoyi-message 的 WechatMpConfigProvider / XinHuaMpSender,调用点不再重复校验
                    log.error("获取微信公众号请求信息根据机构ID:{}", patArchive.getOrgid());
                    if (!"xh".equals(active)) {
                        //市一:走自有公众号网关(不做机构配置校验、his患者id校验,与原实现一致)
                        sendWechatByActive(serviceSubtask, patArchive, url);
                    } else {
                        //新华:his患者id校验失败即记录并进入下一种发送方式
                        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.setResult("fail");
                            serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
                            serviceSubtaskRecord.setRemark("公众号发送失败");
                            log.error("公众号发送失败:{}", e.getMessage());
                            lssubIds.add(serviceSubtask.getId());
                            serviceSubtaskRecord.setRemark(wechatSendResult.getMessage());
                            serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
                            //在子任务表里记录一下
                            setFailPreachForm(serviceSubtask, sendPreachform, "公众号发送失败", "5");
                            continue;
                        }
                        //在子任务表里记录一下
                        String uuid = UUID.randomUUID().toString();
                        serviceSubtask.setResult("success");
                        serviceSubtask.setRemark("公众号发送成功");
                        serviceSubtask.setGuid(uuid);
                        serviceSubtask.setSendstate(3L);
                        serviceSubtask.setFinishtime(new Date());
                        serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                        //任务发送记录
                        ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                        serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
                        serviceSubtaskRecord.setUuid(uuid);
                        serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
                        serviceSubtaskRecord.setPreachform("5");
                        serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
                        serviceSubtaskRecord.setResult("success");
                        serviceSubtaskRecord.setRemark("公众号发送成功");
                        serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
                    }
                    if (CollectionUtils.isEmpty(lssubIds)) {
                        //如果“临时子任务”为空,说明全发送完了
                        isSend = true;
                    }
                    //将子任务ID清空,将“临时子任务”数据 放到 “子任务” 中
                    subIds.clear();
                    subIds.addAll(lssubIds);
                    lssubIds.clear();
                } catch (Exception e) {
                    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.setResult("fail");
                    serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
                    serviceSubtaskRecord.setRemark("公众号发送失败");
                    log.error("公众号发送失败:{}", e.getMessage());
                    serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
                    //失败记录
                    setFailPreachForm(serviceSubtask, sendPreachform, "公众号发送失败", "5");
                    continue;
                }
                //通知 MQ 消息已被接收,可以ACK(从队列中删除)了   (这个需要根据业务再去处理ACK)
                //在子任务表里记录一下
                setFailPreachForm(serviceSubtask, sendPreachform, "公众号发送成功", "2");
                //任务发送记录
                ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
                serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
                serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
                serviceSubtaskRecord.setPreachform("5");
                serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
                serviceSubtaskRecord.setResult("success");
                serviceSubtaskRecord.setRemark("公众号发送成功");
                serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
            } else if (descByCode.equals("人工")) {
                setFailPreachForm(serviceSubtask, sendPreachform, "人工超时", "7");
            } else if (descByCode.equals("微信小程序")) {
                setFailPreachForm(serviceSubtask, sendPreachform, "微信小程序待执行", "2");
            }
            if (CollectionUtils.isNotEmpty(subIds)) {
                //如果全部的发送方式都发完了,还有是未发送的,需要去subTask表中,记录一下,发送失败
                for (Long id : subIds) {
                    ServiceSubtask serviceSubtask = new ServiceSubtask();
                    serviceSubtask.setResult("error");
                    serviceSubtask.setRemark("发送失败");
        }
    }
    /**
     * 按 {@code active}(站点)路由到对应的短信发送方。
     * <p>
     * 入参沿用原分支里已经组装好的 {@code SendMagParam},保证内容与线上完全一致。
     * 各站点差异见 {@code ruoyi-message} 模块各实现类。
     * <p>
     * ⚠️ 新华({@code xh})在本入口原本走「URL 编码表单」,
     * 与 {@code RyTask}(发空报文)/ {@code smsSubTask}(JSON)并不一致;
     * 这里按原样走 {@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 患者id 校验,标题/内容都取任务名称;</li>
     *   <li>新华({@code xh}):要求 his 患者id 非空,患者姓名取 {@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系统的患者id为空", 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) {
        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, org.apache.commons.lang3.StringUtils.isNotEmpty(map.get(key)) ? map.get(key) : "");
            }
        }
        scriptContent = scriptContent.replace("${name}", org.apache.commons.lang3.StringUtils.isNotEmpty(serviceSubtask.getSendname()) ? serviceSubtask.getSendname() : "");
        scriptContent = scriptContent.replace("${dzz}", org.apache.commons.lang3.StringUtils.isNotEmpty(serviceSubtask.getAddr()) ? serviceSubtask.getAddr() : "");
        scriptContent = scriptContent.replace("${phone}", org.apache.commons.lang3.StringUtils.isNotEmpty(serviceSubtask.getTelcode()) ? serviceSubtask.getTelcode() : "");
        return scriptContent;
    }
    private Map<String, Map<String, String>> getParam(Long taskId) {
        ServiceTask serviceTask = serviceTaskMapper.selectServiceTaskByTaskid(taskId);
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Map<String, String>> serviceTaskMap = null;
        try {
            serviceTaskMap = objectMapper.readValue(serviceTask.getTextParam(), Map.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return serviceTaskMap;
    }
    private Date getNextVisitTime(Long subid, Long taskid, Date visitTime, String currentPreachform) {
        ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
        serviceSubtaskPreachform.setSubid(subid);
        serviceSubtaskPreachform.setTaskid(taskid);
        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;
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(visitTime);
            calendar.add(Calendar.HOUR_OF_DAY, hoursToAdd);
            Date newDate = calendar.getTime();
            return newDate;
        }
        return visitTime;
    }
    private String getSendPreachform(ServiceSubtaskPreachform serviceSubtaskPreachform, ServiceSubtask serviceSubtask) {
        log.info("-----getSendPreachform的serviceSubtaskPreachform入参:{},------serviceSubtask:{}", serviceSubtaskPreachform, serviceSubtask);
        List<ServiceSubtaskPreachform> serviceSubtaskPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
        if (CollectionUtils.isEmpty(serviceSubtaskPreachforms)) {
            //如果serviceSubtaskPreachforms为空的话,则需要进行新增一下
            List<ServiceSubtaskPreachform> serviceSubtaskPreachformList = addServiceSubtaskPreachform(serviceSubtask, "1");
            if (CollectionUtils.isEmpty(serviceSubtaskPreachformList)) {
                log.error("发送方式失败了serviceSubtask的入参为:{}", serviceSubtask);
                return null;
            }
            serviceSubtaskPreachforms = serviceSubtaskPreachformList;
        }
        // 情况1:currentPreachform为空,取sort为1的preachform
        if (StringUtils.isEmpty(serviceSubtask.getCurrentPreachform())) {
            String firstPreachform = serviceSubtaskPreachforms.stream().filter(item -> item.getSort() == 1L).map(ServiceSubtaskPreachform::getPreachform).findFirst().orElse(null);
            serviceSubtaskPreachform.setPreachform(firstPreachform);
            serviceSubtaskPreachform.setCurrentSendTime(new Date());
            serviceSubtaskPreachformMapper.updateSSPByCondition(serviceSubtaskPreachform);
            return firstPreachform;
        }
        // 情况2:currentPreachform不为空,找下一个sort
        Optional<Long> currentSort = serviceSubtaskPreachforms.stream().filter(item -> serviceSubtask.getCurrentPreachform().equals(item.getPreachform())).map(ServiceSubtaskPreachform::getSort).findFirst();
        if (currentSort.isPresent()) {
            // 检查是否所有sendstate不等于9
            boolean allSendStateNot1AndNot9 = serviceSubtaskPreachforms.stream().allMatch(item -> !item.getSendstate().equals("9"));
            // 当sort等于列表size时,并且所有sendstate都不等于9,则返回-1
            if (currentSort.get().equals((long) serviceSubtaskPreachforms.size())) {
                if (allSendStateNot1AndNot9) {
                    //说明全发送失败了
                    serviceSubtask.setSendstate(5L);
                    serviceSubtask.setId(id);
//                    serviceSubtask.setFinishtime(new Date());
                    serviceSubtask.setUpdateTime(new Date());
                    serviceSubtask.setRemark("-----getSendPreachform,发送方式全部失败");
                    serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                }
                return "-1";
            }
            // 当sort等于列表size时,下一个sort为-1
            Long nextSort = currentSort.get() + 1;
            // 找到下一个sort对应的preachform
            return serviceSubtaskPreachforms.stream().filter(item -> nextSort.equals(item.getSort())).map(ServiceSubtaskPreachform::getPreachform).findFirst().orElse(null);
        }
        return null;
    }
    //    /**
//     * 机器人第一句话语音
//     * concurrency = "50"  并发数为50
//     */
//    @RabbitListener(queues = "ob_queue", concurrency = "50")
//    public void obVisit(String content, Message message, Channel channel) throws IOException {
//        try {
//            IvrTaskcallPhoneMQ commonTaskcallMQ = null;
//            ObjectMapper mapper = new ObjectMapper();
//            commonTaskcallMQ = mapper.readValue(content, IvrTaskcallPhoneMQ.class);
//            //判断患者是否已经接电话
//            String str = redisCache.getCacheObject(commonTaskcallMQ.getUuid() + "state_id");
//            System.out.println("-----------------" + str);
//            if (StringUtils.isNotEmpty(str) && str.equals("0")) {
//                //患者已经接听了电话
//                new PhoneUtils().ttsPlayback(commonTaskcallMQ.getScript(), commonTaskcallMQ.getUuid());
//            } else if (StringUtils.isNotEmpty(str) && str.equals("-10")) {
//                //这个说明,已经打了指定遍数还是没有人接,可以将消息从队列中移除了
//                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
//                return;
//            } else {
//                //进行队列尾部,进行下一次校验
////                channel.basicRecover(false);
//                channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
//                System.out.println("++++++++++++++++++++++" + str);
//                return;
//            }
//            //通知 MQ 消息已被接收,可以ACK(从队列中删除)了   (这个需要根据业务再去处理ACK)
//            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
//        } catch (Exception e) {
//            log.error("============消费失败,尝试消息补发再次消费!==============");
//            log.error(e.getMessage());
//            channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
//        }
//    }
    private String getKey() {
        Map<String, String> map = new HashMap<>();
        for (int i = 0; i < 6; i++) {
            Boolean aBoolean = redisCache.hasKey("cache-" + i);
            if (!aBoolean) {
                redisCache.setCacheObject("cache-" + i, "");
                map.put("cache-" + i, "");
            } else {
                map.put("cache-" + i, redisCache.getCacheObject("cache-" + i));
    private List<ServiceSubtaskPreachform> addServiceSubtaskPreachform(ServiceSubtask serviceSubtask, String sendstate) {
        //将preachformDesc的json对象,放到list集合中
        ServiceTask serviceTask = serviceTaskMapper.selectServiceTaskByTaskid(serviceSubtask.getTaskid());
        String preachformDesc = serviceTask.getPreachformDesc();
        List<ServiceSubtaskPreachform> sspl = null;
        ObjectMapper objectMapper = new ObjectMapper();
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(preachformDesc)) {
            try {
                sspl = objectMapper.readValue(preachformDesc, new TypeReference<List<ServiceSubtaskPreachform>>() {
                });
            } catch (JsonProcessingException e) {
                log.error("mq--preachform转List<ServiceSubtaskPreachform>报错了:{}", e.getMessage());
            }
            for (ServiceSubtaskPreachform serviceSubtaskPreachform : sspl) {
                serviceSubtaskPreachform.setTaskid(serviceSubtask.getTaskid());
                serviceSubtaskPreachform.setSubid(serviceSubtask.getId());
                //这个sendstate需要在数据库设置一个默认值为“1”
                serviceSubtaskPreachform.setSendstate("1");
                if (StringUtils.isNotEmpty(sendstate)) serviceSubtaskPreachform.setSendstate(sendstate);
                serviceSubtaskPreachform.setOrgid(serviceSubtask.getOrgid());
                serviceSubtaskPreachformMapper.insertServiceSubtaskPreachform(serviceSubtaskPreachform);
            }
        }
        String key = null;
        String value = "";
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (StringUtils.isEmpty(value)) {
                value = entry.getValue();
                key = entry.getKey();
            } else {
                if (entry.getValue().split(",").length < value.split(",").length) {
                    value = entry.getValue();
                    key = entry.getKey();
        return sspl;
    }
    /**
     * @param serviceSubtask
     * @param preachform
     * @param remark
     * @param failSendstate
     * @return
     */
    public Boolean setFailPreachForm(ServiceSubtask serviceSubtask, String preachform, String remark, String failSendstate) {
        log.info("^^^^^^^^^--------setFailPreachForm的入参为serviceSubtask:{}   ,preachform值为:{},  failSendstate:{}", serviceSubtask, preachform, failSendstate);
        if (preachform.equals("-1")) {
            //说明都不需要执行了
            ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
            serviceSubtaskPreachform.setSubid(serviceSubtask.getId());
            serviceSubtaskPreachform.setTaskid(serviceSubtask.getTaskid());
            serviceSubtaskPreachform.setOrgid(serviceSubtask.getOrgid());
            serviceSubtaskPreachform.setSendstate(failSendstate);
            serviceSubtaskPreachform.setCurrentSendTime(new Date());
            if (serviceSubtask.getType().equals("3") || serviceSubtask.getType().equals("4")) {
                //如果是宣教或通知,并且发送成功,直接将发送状态改成9
                if (failSendstate.equals("2")) 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,因为,数据可能卡在队列里了(也有可能没有拉取,sendstate=1,所以如果是电话状态判断serviceSubtaskPreachforms是不是为空)
        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);
            //如果当前的preachform已经是最后一个了,并且本次还是发送失败,那直接将serviceSubtask的sendstate状态改成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 {
            log.error("【MQ中该患者没有查询到属于他的发送方式,subid:{},prechform:{},orgid:{}】", serviceSubtask.getId(), preachform, serviceSubtask.getOrgid());
            return false;
        }
        return key;
        log.info("^^^^^^^^^--------preachform的值为:{}", preachform);
        serviceSubtask.setCurrentPreachform(preachform);
        serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime(), serviceSubtask.getCurrentPreachform()));
        serviceSubtask.setSendstate(3L);
        if (serviceSubtask.getType().equals("3") || serviceSubtask.getType().equals("4")) {
            //如果是宣教或通知,并且发送成功,则直接将serviceSubtask状态改成6L(这个患者是没有题做的,不会再触发接口进行状态修改)
            if (failSendstate.equals("2")) {
                serviceSubtask.setSendstate(6L);
            }
        }
        serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
        return true;
    }
    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);
    private String getKey() {
        String targetKey = null;
        long minSize = Long.MAX_VALUE;
        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);
        for (int i = 1; i < 6; i++) {
            String key = "cache-" + i;
        JSONObject jsonObject = JSONObject.parseObject(result);
        String code = (String) jsonObject.toString();
        return code;
            // 获取 list 的长度(即 value 的元素个数)
            Long size = redisCache.getListSize(key);
            if (size == null) {
                size = 0L; // 如果 key 不存在,认为是 0
            }
            // 取最小值
            if (size < minSize) {
                minSize = size;
                targetKey = key;
            }
        }
        return targetKey;
    }
    // ---------------------------------------------------------------------
    // 说明:原 getWXCode / getDXCode / encode 三个私有方法已随发送方一起收口到
    // ruoyi-message 模块(XinHuaMpApi / LishuiSmsSender),此处已删除,避免重复实现。
    // 注意:本类的 getWXCode 原使用 new GsonBuilder().disableHtmlEscaping(),
    //      与 RyTask.getWXCode 的 new Gson() 不同,该差异已在 XinHuaMpApi 中按站点保留。
    // ---------------------------------------------------------------------
    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 = HttpUtils.sendPost(address, body);
        String result = null;
        try {
            result = OkHttpExample.sendPostRequest(address, body, token);
        } catch (IOException e) {
            e.printStackTrace();
    /**
     * 随访任务是否超时
     * @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;
            }
        }
        log.error("--------result的值为:{}-----", result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        String code = (String) jsonObject.toString();
        return code;
    }
    public String encode(String arg) {
        if (arg == null) {
            arg = "";
        if (Objects.isNull(serviceSubtask) || CollectionUtils.isEmpty(serviceSubtaskPreachforms)) {
            return false;
        }
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            md5.update(arg.getBytes("UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return toHex(md5.digest());
        // 基准时刻:出院时间 + 发送日(sendDay 缺省按 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();
    }
}