liusheng
2024-04-15 fdf1b9c1e4489a0c2615fa596268b2f71fad7b4c
代码提交
已添加17个文件
已修改49个文件
3295 ■■■■ 文件已修改
ruoyi-admin/pom.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/aa.puml 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/component/RabbitMqReceiver.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/hanler/ChatWebSocketHandler.java 279 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/IvrLibaExtemplateController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/IvrLibaExtemplatescriptController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/IvrLibaTemplateController.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/IvrTaskcallController.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/tools/PersonVoiceController.java 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/task/PhoneTask.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/test/MQTest.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-druid.yml 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/logback.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/pom.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/exception/HttpRequestException.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtil.java 358 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java 117 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpBody.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpEntity.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/json/JsonRequestBody.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/json/JsonResponseBody.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/xml/XmlRequestBody.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/xml/XmlResponseBody.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/config/PhoneUtils.java 275 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/config/RabbitMqConfig.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrLibaExtemplate.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrLibaExtemplatescript.java 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrLibaScriptTargetoption.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrLibaTargetoption.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrLibaTemplate.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrLibaTemplateScript.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrLibaTemplateScriptVO.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrLibaTemplateTargetoption.java 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrLibaTemplateVO.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrTaskcall.java 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrTaskcallMQ.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrTaskcallVO.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/QuestionMessage.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/SocketMessage.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/TaskSendTimeVO.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/mapper/IvrLibaExtemplateMapper.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/mapper/IvrLibaExtemplatescriptMapper.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/mapper/IvrTaskcallMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/IIvrLibaExtemplateService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/IIvrLibaExtemplatescriptService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/IIvrTaskcallService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/PersonVoiceService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/IvrLibaExtemplateServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/IvrLibaExtemplatescriptServiceImpl.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/IvrLibaScriptServiceImpl.java 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/IvrLibaTargetServiceImpl.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/IvrLibaTemplateServiceImpl.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/IvrTaskcallServiceImpl.java 346 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/PersonVoiceServiceImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/IvrLibaExtemplateMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/IvrLibaExtemplatescriptMapper.xml 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/IvrLibaTemplateMapper.xml 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/IvrLibaTemplateScriptMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/IvrLibaTemplateTargetoptionMapper.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/IvrTaskcallMapper.xml 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/pom.xml
@@ -130,7 +130,11 @@
            <artifactId>nls-sdk-common</artifactId>
            <version>2.1.6</version>
        </dependency>
        <!-- rabbitmq ä¾èµ–-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
    </dependencies>
    <build>
ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
@@ -29,7 +29,7 @@
                " |  | \\ `'   /|   `-'  /           \n" +
                " |  |  \\    /  \\      /           \n" +
                " ''-'   `'-'    `-..-'              ");
        //开启SOCKET
        new SocketCommunication().socketCommunication();
//        //开启SOCKET
//        new SocketCommunication().socketCommunication();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/aa.puml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,170 @@
@startuml
start
:入参,userid,socketMessage;
    note right
           //发送内空的类型(text,image)
            private String type;
            //内容(这个是在开发测试的时候用)
            private String content;
            //模板ID
            private Long templateId;
            //问题信息
            private QuestionMessage questionMessage;
            //用户ID(接收放)
            private String userId;
            //图片
            private String image;
            //图片,音、视频的字节大小
            private Integer fileSize;
    end note
if (如果模板id不为空,socketMessage.getTemplateId() != null) then(不为空)
      partition "通过模板ID获取模板问题" {
            :通过模板ID获取模板信息,并将信息放到redis中,
            key为userId + "ivrLibaTemplateVO1",过期时间2小时;
            note left
                ç›´æŽ¥è°ƒç”¨ivrLibaTemplateService.selectInfoByCondition
                èŽ·å–åˆ°â€œæ¨¡æ¿ä¿¡æ¯â€ã€â€œé—®é¢˜è¯æœ¯â€ã€â€œè¯æœ¯é€‰é¡¹â€
             end note
            :从返回的模板信息中获取问题话术集合
            å¹¶å°†é›†åˆæ”¾åˆ°redis中,key为userId + "ivrLibaTemplateScriptVOList";
            note left
                  List<IvrLibaTemplateScriptVO> ivrLibaTemplateScriptVOList
                  æ ¹æ®IvrLibaTemplateScriptVO中的Targetid(暂时当一个问题的序号)
                  æŽ’序一下
             end note
            :定义一些redis,这里之所以大量用redis,是用来进行多进程隔离;
            note left
                   userId + "backQuset" ç”¨æ¥è¿”回调查的总结果
                   userId + "noVoice"   ç”¨æ¥è®°å½•无声响应次数
                   userId + "mateNum"   ç”¨æ¥è®°å½•无匹配次数
                   userId + "isOver"    ç”¨æ¥è®°å½•整个问卷是否结束 0 ï¼šæœªç»“束     1:结束
            end note
             :从ivrLibaTemplateScriptVOList中获取到targetid为1的题
             æ”¾åˆ°QuestionMessage中;
             note left
               QuestionMessage的字段为
                        String content è¿”回的内容
                        String kcb å¼€åœºç™½
                        String jsy ç»“束语
                        IvrLibaTemplateScriptVO nowQuestion å½“前问题
              end note
             :定义“开场白”,
             å’Œ userId + "returnQues" çš„redis;
    }
else (为空)
    :获取前端返回的questionMessage“问题信息”;
    :去redis中获取到“话术问题集合”
    List<IvrLibaTemplateScriptVO> ivrLibaTemplateScriptVOList;
    :获取到当前的要问题的问题从questionMessage中,
     IvrLibaTemplateScriptVO ivrLibaTemplateScriptVO;
    :去redis中获取模板信息,IvrLibaTemplateVO ivrLibaTemplateVO1;
    if(questionMessage的content为空,说明对方没有回答) then(true)
      partition "静默话术" {
           :先去redis中,获取当前用户的对该题的实际静默次数 Integer noVoice;
           if(实际静默次数是否等于模板中配置的次数,noVoice == ivrLibaTemplateVO1.getNoVoiceNum().intValue()) then(true)
                 :该题记录到调查的总结果中,即backQuset中,更新redis中的userId + "backQuset";
                 if(本题的targetid ç­‰äºŽ é¢˜ç›®æ•°é‡çš„æœ€å¤§å€¼ï¼Œå³ivrLibaTemplateScriptVO.getTargetid() == ivrLibaTemplateScriptVOList.size()) then(true)
                     :说明这就是最后一道题了,将调查的结果,和结束语放到对象中,进行返回给用户;
                     note right
                         List<IvrLibaTemplateScriptVO> backQusetRedis = redisCache.getCacheObject(userId + "backQuset");
                          returnQues.setContent(JSON.toJSONString(backQusetRedis));
                          returnQues.setJsy("感谢您的耐心回答,再见");
                          redisCache.setCacheObject(userId + "returnQues", returnQues, 120, TimeUnit.MINUTES);
                          redisCache.setCacheObject(userId + "isOver", 1, 120, TimeUnit.MINUTES);
                     end note
                 else(不等于)
                     :则还有下一题,就根据当前teagetID+1 èŽ·å–ä¸‹ä¸€é¢˜
                      å¹¶å°†ä¸‹ä¸€é¢˜çš„信息放到reids中,key为userId + "returnQues", returnQues
                      å°†userId + "noVoice"清零;
                 endif
           else(实际静默次数是否 ä¸ç­‰äºŽ æ¨¡æ¿ä¸­é…ç½®çš„æ¬¡æ•°) then(false)
                 :进行再将询问;
                 :去redis中获取userId + "noVoice"(实际的静默次数),得到Integer noVoice2
                  å¯¹å®žé™…静默次数加1,再放回reids中;
             endif
     }
    else (对方有回答) then(false)
         partition "循环本题的选项,ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList()" {
               :获取循环,获取到选项的正则匹配,
                å†èŽ·å–åˆ°ç”¨æˆ·çš„å›žç­”ä¿¡æ¯ï¼Œè¿›è¡Œæ­£åˆ™åŒ¹é…;
                note right
                        Pattern pattern = Pattern.compile(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex());
                        Matcher matcher = pattern.matcher(questionMessage.getContent());
                end note
                if(匹配到了) then(matcher.matches()为true)
                        :则将该选项中的IsUserOperation,设置成true(前端会根据这个拿值);
                        :去redis中获取userId + "backQuset",得到 List<IvrLibaTemplateScriptVO> backQuset;
                        :将该题的信息放到backQuset中;
                        :更新redis中的userId + "backQuset",并将userId + "noVoice"置为0;
                        :结束当前循环;
                        :通过当前正确选项的nextQeestion,获取下一题的targetID,再去ivrLibaTemplateScriptVOList,
                        è¿›è¡ŒåŒ¹é…ï¼ŒèŽ·å–IvrLibaTemplateScriptVO(下一题的信息);
                        :将获取到的题信息放到redis中,key为userId + "returnQues";
                else(没匹配到)
                        :去redis中获取userId + "mateNum",得到Integer mateNum(无匹配次数);
                        :无匹配次数去判断是否到最大询问次数,并且是否所有的选项都匹配完了;
                        if(无匹配次数“等于”最大询问次数,并且所有的选项都匹配完了) then(true)
                             :去redis中获取userId + "backQuset",得到 List<IvrLibaTemplateScriptVO> backQuset;
                             :将该题的信息放到backQuset中,更新redis中的userId + "backQuset";
                             :判断是否还有下一题;
                             if(本题的targetid < æ€»é¢˜æ•°) then(有下一题)
                                    :则还有下一题,就根据当前teagetID+1 èŽ·å–ä¸‹ä¸€é¢˜
                                     å¹¶å°†ä¸‹ä¸€é¢˜çš„信息放到reids中,key为userId + "returnQues",
                                     å°†userId + "mateNum"清零;
                             else(没有题了)
                                    :定义一个空的QuestionMessage returnQues2(用于返参);
                                    :去reids中获取userId + "backQuset",放到returnQues2的content中;
                                    :给returnQues2设置结束语;
                                    :更新redis中的userId + "returnQues";
                                    :将redis中的userId + "isOver"值,设置为1(表示整个流程结束);
                              endif
                        else(无匹配次数“小于”最大询问次数,并且所有的选项都匹配完了)
                            :无匹配次数+1,更新redis中的userId + "mateNum";
                         endif
                 endif
         }
         :选项匹配完成后,需要再去通过库再进行匹配一次;
         :去模板信息中获取通过库模板ID集合;
         note right
            String extemplateID = ivrLibaTemplateVO1.getSubmoduleID();
         end note
         if(通用库模板ID集合不为空) then(true)
             :通过通用库模板ID获取通过话术信息集合;
             note right
                     List<IvrLibaExtemplatescript> ivrLibaExtemplatescripts = ivrLibaExtemplatescriptMapper.queryIvrLibaExtemplatescriptList(list1);
             end note
             partition "循环通用话术集合List<IvrLibaExtemplatescript> ivrLibaExtemplatescripts" {
                 :通过正则将前端传回的结果,和遍历出来的话术正则进行匹配;
                 :匹配到后,去redis中获取userId + "returnQues",将答案放到问题对象中的submoduleText中;
                  note right
                        QuestionMessage returnQues = redisCache.getCacheObject(userId + "returnQues");
                        IvrLibaTemplateScriptVO nowQuestion = returnQues.getNowQuestion();
                        nowQuestion.setSubmoduleText(ivrLibaExtemplatescript.getSwitchText());
                        nowQuestion.setSubmoduleVoice(ivrLibaExtemplatescript.getSwitchWav());
                        redisCache.setCacheObject(userId + "returnQues", returnQues, 120, TimeUnit.MINUTES);
                  end note
              }
           :结束循环;
          endif
    endif
endif
:去redis中获取userId + "returnQues",将结果返回给前端;
:清空redis所有的变量;
note left
      //整个流程是否结束,将redis中的该userId下的数据删除;
      Integer isOver = redisCache.getCacheObject(userId + "isOver");
       if (isOver == 1) {
          redisCache.deleteObject(userId + "ivrLibaTemplateScriptVOList");
          redisCache.deleteObject(userId + "backQuset");
          redisCache.deleteObject(userId + "noVoice");
          redisCache.deleteObject(userId + "returnQues");
          redisCache.deleteObject(userId + "isOver");
          redisCache.deleteObject(userId + "ivrLibaTemplateVO1");
       }
end note
stop
@enduml
ruoyi-admin/src/main/java/com/ruoyi/web/component/RabbitMqReceiver.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,118 @@
package com.ruoyi.web.component;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.web.task.PhoneTask;
import com.smartor.config.RabbitMqConfig;
import com.smartor.domain.IvrLibaTemplateVO;
import com.smartor.domain.IvrTaskcall;
import com.smartor.domain.IvrTaskcallMQ;
import com.smartor.mapper.IvrTaskcallMapper;
import com.smartor.service.IIvrLibaTemplateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.Channel;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j
@Component//监听此队列
public class RabbitMqReceiver {
    private static IIvrLibaTemplateService ivrLibaTemplateService;
    private static IvrTaskcallMapper ivrTaskcallMapper;
    private static RedisCache redisCache;
    // åˆ›å»ºå›ºå®šå¤§å°çš„线程池
    private static final ExecutorService executorService = Executors.newFixedThreadPool(10);
    @Autowired
    public void setIIvrLibaTemplateService(IIvrLibaTemplateService ivrLibaTemplateService) {
        RabbitMqReceiver.ivrLibaTemplateService = ivrLibaTemplateService;
    }
    @Autowired
    public void setIvrTaskcallMapper(IvrTaskcallMapper ivrTaskcallMapper) {
        RabbitMqReceiver.ivrTaskcallMapper = ivrTaskcallMapper;
    }
    @Autowired
    public void setRedisCache(RedisCache redisCache) {
        RabbitMqReceiver.redisCache = redisCache;
    }
//    @RabbitListener(queues = RabbitMqConfig.delay_queue)
//    public void consultReceiveDealy(String content, Message message, Channel channel) throws IOException {
//        log.info("----------------接收延迟队列消息--------------------");
//        //通知 MQ æ¶ˆæ¯å·²è¢«æŽ¥æ”¶,可以ACK(从队列中删除)了
//        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
//        try {
//            log.info("=============Do Something==============");
//        } catch (Exception e) {
//            log.error("============消费失败,尝试消息补发再次消费!==============");
//            log.error(e.getMessage());
//            /**
//             * basicRecover方法是进行补发操作,
//             * å…¶ä¸­çš„参数如果为true是把消息退回到queue但是有可能被其它的consumer(集群)接收到,
//             * è®¾ç½®ä¸ºfalse是只补发给当前的consumer
//             */
//            channel.basicRecover(false);
//        }
//    }
    /**
     * ç”µè¯éšè®¿
     * concurrency = "50"  å¹¶å‘数为50
     */
    @RabbitListener(queues = RabbitMqConfig.phone_queue, concurrency = "50")
    public void phoneVisit(String content, Message message, Channel channel) throws IOException {
//        System.out.println(content);
//        IvrTaskcallMQ ivrTaskcallMQ = null;
//        ObjectMapper mapper = new ObjectMapper();
//        try {
//            ivrTaskcallMQ = mapper.readValue(content, IvrTaskcallMQ.class);
//        } catch (JsonProcessingException e) {
//            e.printStackTrace();
//        }
//        //通过模板ID获取模板问题
//        IvrLibaTemplateVO ivrLibaTemplateVO = new IvrLibaTemplateVO();
//        ivrLibaTemplateVO.setID(Long.valueOf(ivrTaskcallMQ.getTemplateid()));
//        IvrLibaTemplateVO ivrLibaTemplateVO1 = ivrLibaTemplateService.selectInfoByCondition(ivrLibaTemplateVO);
//
//        //通过任务ID拿到患者信息
//        IvrTaskcall ivrTaskcall = new IvrTaskcall();
//        ivrTaskcall.setTaskid(ivrTaskcallMQ.getTaskid());
//        List<IvrTaskcall> ivrTaskcalls = ivrTaskcallMapper.selectIvrTaskcallList(ivrTaskcall);
//
//        for (IvrTaskcall ivrTaskcall1 : ivrTaskcalls) {
//            //通过多线程的方式去打电话
//            executorService.submit(new PhoneTask(ivrTaskcall1, ivrLibaTemplateVO1, redisCache));
//        }
        //通知 MQ æ¶ˆæ¯å·²è¢«æŽ¥æ”¶,可以ACK(从队列中删除)了   ï¼ˆè¿™ä¸ªéœ€è¦æ ¹æ®ä¸šåŠ¡å†åŽ»å¤„ç†ACK)
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        try {
            log.info("=============Do Something==============");
        } catch (Exception e) {
            log.error("============消费失败,尝试消息补发再次消费!==============");
            log.error(e.getMessage());
            /**
             * basicRecover方法是进行补发操作,
             * å…¶ä¸­çš„参数如果为true是把消息退回到queue但是有可能被其它的consumer(集群)接收到,
             * è®¾ç½®ä¸ºfalse是只补发给当前的consumer
             */
            channel.basicRecover(false);
        }
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/hanler/ChatWebSocketHandler.java
@@ -1,8 +1,15 @@
package com.ruoyi.web.controller.hanler;
import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.smartor.domain.SocketMessage;
import com.google.gson.Gson;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.smartor.domain.*;
import com.smartor.mapper.IvrLibaExtemplatescriptMapper;
import com.smartor.service.IIvrLibaTemplateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
@@ -11,16 +18,40 @@
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
import java.io.IOException;
import java.util.Map;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
@Component
public class ChatWebSocketHandler extends AbstractWebSocketHandler {
    private static RedisCache redisCache;
    private static IIvrLibaTemplateService ivrLibaTemplateService;
    private static IvrLibaExtemplatescriptMapper ivrLibaExtemplatescriptMapper;
    // ç”¨äºŽå­˜å‚¨ç”¨æˆ·ID和WebSocketSession的映射关系
    private static Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
    @Autowired
    public void setIEMapper(IvrLibaExtemplatescriptMapper ivrLibaExtemplatescriptMapper) {
        ChatWebSocketHandler.ivrLibaExtemplatescriptMapper = ivrLibaExtemplatescriptMapper;
    }
    @Autowired
    public void setTodayReaderService(IIvrLibaTemplateService ivrLibaTemplateService) {
        ChatWebSocketHandler.ivrLibaTemplateService = ivrLibaTemplateService;
    }
    @Autowired
    public void setRedisCache(RedisCache redisCache) {
        ChatWebSocketHandler.redisCache = redisCache;
    }
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
@@ -42,7 +73,7 @@
        ObjectMapper mapper = new ObjectMapper();
        SocketMessage parsedMessage = mapper.readValue(payload, SocketMessage.class);
        if (parsedMessage != null) {
            sendMessageToUser(parsedMessage.getUserId(), parsedMessage.getContent());
            sendMessageToUser(parsedMessage.getUserId(), parsedMessage);
        }
    }
@@ -79,12 +110,250 @@
        return userId;
    }
    private void sendMessageToUser(String userId, String message) throws IOException {
    private void sendMessageToUser(String userId, SocketMessage socketMessage) throws IOException {
        WebSocketSession session = sessions.get(userId);
        if (session != null && session.isOpen()) {
            session.sendMessage(new TextMessage(message));
            if (socketMessage.getTemplateId() != null) {
                //通过模板ID获取模板问题
                IvrLibaTemplateVO ivrLibaTemplateVO = new IvrLibaTemplateVO();
                ivrLibaTemplateVO.setID(socketMessage.getTemplateId());
                IvrLibaTemplateVO ivrLibaTemplateVO1 = ivrLibaTemplateService.selectInfoByCondition(ivrLibaTemplateVO);
                redisCache.setCacheObject(userId + "ivrLibaTemplateVO1", ivrLibaTemplateVO1, 120, TimeUnit.MINUTES);
                //将查出来的问题,放到全局变量中去
                List<IvrLibaTemplateScriptVO> ivrLibaTemplateScriptVOList = ivrLibaTemplateVO1.getIvrLibaTemplateScriptVOList();
                //根据序号进行排序
                Collections.sort(ivrLibaTemplateScriptVOList, Comparator.comparing(IvrLibaTemplateScriptVO::getTargetid));
                //将查出来的数据放到redis中
                redisCache.setCacheObject(userId + "ivrLibaTemplateScriptVOList", ivrLibaTemplateScriptVOList, 120, TimeUnit.MINUTES);
                //用来返回调查的总结果
                redisCache.setCacheObject(userId + "backQuset", new ArrayList<>(), 120, TimeUnit.MINUTES);
                //用来记录无声响应次数
                redisCache.setCacheObject(userId + "noVoice", 0, 120, TimeUnit.MINUTES);
                //用来记录无匹配次数
                redisCache.setCacheObject(userId + "mateNum", 0, 120, TimeUnit.MINUTES);
                //用来记录整个问卷是否结束 0 ï¼šæœªç»“束     1:结束
                redisCache.setCacheObject(userId + "isOver", 0, 120, TimeUnit.MINUTES);
                //用来返回当前需要问的问题信息
                QuestionMessage returnQues = new QuestionMessage();
                for (IvrLibaTemplateScriptVO ivrLibaTemplateScriptVO : ivrLibaTemplateScriptVOList) {
                    if (ivrLibaTemplateScriptVO.getTargetid() == ivrLibaTemplateVO1.getFirstQuestionNum().intValue())
                        //获取第一题的问题
                        returnQues.setNowQuestion(ivrLibaTemplateScriptVO);
//                        returnQues.setCode(ivrLibaTemplateScriptVO.getTargetid() + 1);
                }
//                returnQues.setKcb("你好,大傻狗,我们是某某某医院,现在需要做一次随访;");
                returnQues.setKcb(ivrLibaTemplateVO1.getRevisitBefore());
                //记录响应
                redisCache.setCacheObject(userId + "returnQues", returnQues, 120, TimeUnit.MINUTES);
            } else {
                //获取socketMessage里的QuestionMessage,对答案进行处理然后,再问下一道
                Gson gson = new Gson();
                if (!StringUtils.isEmpty(socketMessage.getContent())) {
                    socketMessage.setQuestionMessage(gson.fromJson(socketMessage.getContent(), QuestionMessage.class));
                }
                QuestionMessage questionMessage = socketMessage.getQuestionMessage();
                List<IvrLibaTemplateScriptVO> ivrLibaTemplateScriptVOList = redisCache.getCacheObject(userId + "ivrLibaTemplateScriptVOList");
                //根据前端传回的条件,获取当前题目
                IvrLibaTemplateScriptVO ivrLibaTemplateScriptVO = questionMessage.getNowQuestion();
                if (ivrLibaTemplateScriptVO.getID() == null) {
                    QuestionMessage returnQues = redisCache.getCacheObject(userId + "returnQues");
                    ivrLibaTemplateScriptVO = returnQues.getNowQuestion();
                }
                //获取模板信息
                IvrLibaTemplateVO ivrLibaTemplateVO1 = redisCache.getCacheObject(userId + "ivrLibaTemplateVO1");
                if (StringUtils.isEmpty(questionMessage.getContent())) {
                    //调用ivrLibaTemplateScriptVO中的slienceText(静默话术)
                    Integer noVoice = redisCache.getCacheObject(userId + "noVoice");
                    //实际静默次数是否 ç­‰äºŽ æ¨¡æ¿ä¸­é…ç½®çš„æ¬¡æ•°
                    if (noVoice == ivrLibaTemplateVO1.getNoVoiceNum().intValue()) {
                        //用来返回调查的总结果
                        List<IvrLibaTemplateScriptVO> backQuset = new ArrayList<>();
                        backQuset.add(ivrLibaTemplateScriptVO);
                        redisCache.setCacheObject(userId + "backQuset", backQuset, 120, TimeUnit.MINUTES);
                        //如果几次都没响应,就下一题(需要先判断是否有下一题)
                        if (ivrLibaTemplateScriptVO.getTargetid() == ivrLibaTemplateScriptVOList.size()) {
                            //如果下一题没有了,就结束了
                            QuestionMessage returnQues = new QuestionMessage();
//                            returnQues.setCode(null);
                            List<IvrLibaTemplateScriptVO> backQusetRedis = redisCache.getCacheObject(userId + "backQuset");
                            returnQues.setContent(JSON.toJSONString(backQusetRedis));
                            returnQues.setJsy("感谢您的耐心回答,再见");
                            redisCache.setCacheObject(userId + "returnQues", returnQues, 120, TimeUnit.MINUTES);
                            redisCache.setCacheObject(userId + "isOver", 1, 120, TimeUnit.MINUTES);
                        } else {
                            //如果有下一题,就根据当前teagetID+1 èŽ·å–ä¸‹ä¸€é¢˜
                            QuestionMessage returnQues = getNextQuestion(ivrLibaTemplateScriptVOList, ivrLibaTemplateScriptVO);
                            redisCache.setCacheObject(userId + "returnQues", returnQues, 120, TimeUnit.MINUTES);
                            redisCache.setCacheObject(userId + "noVoice", 0, 120, TimeUnit.MINUTES);
                        }
                    } else {
                        //实际静默次数是否 ä¸ç­‰äºŽ æ¨¡æ¿ä¸­é…ç½®çš„æ¬¡æ•°
//                        QuestionMessage returnQues = redisCache.getCacheObject(userId + "returnQues");
//                        returnQues.setContent(null);
//                        redisCache.setCacheObject(userId + "returnQues", returnQues, 120, TimeUnit.MINUTES);
                        Integer noVoice2 = redisCache.getCacheObject(userId + "noVoice");
                        noVoice2 = noVoice2 + 1;
                        redisCache.setCacheObject(userId + "noVoice", noVoice2, 120, TimeUnit.MINUTES);
                    }
                } else {
                    //对回答的问题,进行正则匹配(这里只针对选择题,其它题型不行)
                    for (int j = 0; j < ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().size(); j++) {
                        //包含
                        Matcher matcher = null;
                        if (StringUtils.isNotEmpty(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex())) {
                            Pattern pattern = Pattern.compile(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex());
                            matcher = pattern.matcher(questionMessage.getContent());
                        }
                        //不包含
                        Matcher matcher2 = null;
                        if (StringUtils.isNotEmpty(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex2())) {
                            Pattern pattern2 = Pattern.compile(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex2());
                            matcher2 = pattern2.matcher(questionMessage.getContent());
                        }
                        log.info("==============================Targetregex的值为:{},   Targetregex2的值为:{}", ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex(), ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex2());
                        if (StringUtils.isNotEmpty(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex()) && matcher.matches() && StringUtils.isNotEmpty(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex2()) && matcher2.matches() || StringUtils.isEmpty(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex()) && StringUtils.isNotEmpty(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex2()) && matcher2.matches() || StringUtils.isEmpty(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex2()) && StringUtils.isNotEmpty(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex()) && matcher.matches()) {
                            //说明匹配正确了
                            ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).setIsUserOperation(true);
                            List<IvrLibaTemplateScriptVO> backQuset = redisCache.getCacheObject(userId + "backQuset");
                            //匹配完成后,将结果保存到新的数组
                            backQuset.add(ivrLibaTemplateScriptVO);
                            redisCache.setCacheObject(userId + "backQuset", backQuset, 120, TimeUnit.MINUTES);
                            //将静默置为0
                            redisCache.setCacheObject(userId + "noVoice", 0, 120, TimeUnit.MINUTES);
                            //获取下一题
                            Integer nextQuestion = ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getNextQuestion();
                            for (IvrLibaTemplateScriptVO script : ivrLibaTemplateScriptVOList) {
                                if (script.getTargetid() == nextQuestion) {
                                    QuestionMessage returnQues = new QuestionMessage();
                                    returnQues.setNowQuestion(script);
                                    redisCache.setCacheObject(userId + "returnQues", returnQues, 120, TimeUnit.MINUTES);
                                    break;
                                }
                            }
                            break;
                        } else {
                            //没有匹配到
                            Integer mateNum = redisCache.getCacheObject(userId + "mateNum");
                            //无匹配次数去判断是否到最大询问次数,并且所有的选项都匹配完了
                            if (mateNum == ivrLibaTemplateVO1.getMateNum().intValue() && j == ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().size() - 1) {
                                //问了最大询问次数后,还是没有匹配上,将结果保存到新的数组
                                List<IvrLibaTemplateScriptVO> backQuset = redisCache.getCacheObject(userId + "backQuset");
                                backQuset.add(ivrLibaTemplateScriptVO);
                                redisCache.setCacheObject(userId + "backQuset", backQuset, 120, TimeUnit.MINUTES);
                                //如果下一题为空.则新的数据返回,并加上感谢语
                                if (ivrLibaTemplateScriptVO.getTargetid() < ivrLibaTemplateScriptVOList.size()) {
                                    QuestionMessage returnQues = getNextQuestion(ivrLibaTemplateScriptVOList, ivrLibaTemplateScriptVO);
                                    redisCache.setCacheObject(userId + "returnQues", returnQues, 120, TimeUnit.MINUTES);
                                    redisCache.setCacheObject(userId + "mateNum", 0, 120, TimeUnit.MINUTES);
                                } else {
                                    QuestionMessage returnQues2 = new QuestionMessage();
//                                    returnQues2.setCode(null);
                                    List<IvrLibaTemplateScriptVO> backQusetRedis = redisCache.getCacheObject(userId + "backQuset");
                                    returnQues2.setQuestionList(backQusetRedis);
                                    returnQues2.setJsy("感谢您的耐心回答,再见");
                                    redisCache.setCacheObject(userId + "returnQues", returnQues2, 120, TimeUnit.MINUTES);
                                    redisCache.setCacheObject(userId + "isOver", 1, 120, TimeUnit.MINUTES);
                                    break;
                                }
                            } else if (mateNum < ivrLibaTemplateVO1.getMateNum().intValue() && j == ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().size() - 1) {
                                //没有问到规定次数
                                mateNum = mateNum + 1;
                                redisCache.setCacheObject(userId + "mateNum", mateNum, 120, TimeUnit.MINUTES);
                            }
                        }
                    }
                    //选项匹配完成后,需要再去通过库再进行匹配一次
                    String extemplateID = ivrLibaTemplateVO1.getSubmoduleID();
                    String[] split = extemplateID.split(",");
                    List<String> list = Arrays.asList(split);
                    List<Long> list1 = new ArrayList<>();
                    if (StringUtils.isNotEmpty(extemplateID)) {
                        for (String str : list) {
                            list1.add(Long.valueOf(str));
                        }
                        List<IvrLibaExtemplatescript> ivrLibaExtemplatescripts = ivrLibaExtemplatescriptMapper.queryIvrLibaExtemplatescriptList(list1);
                        for (IvrLibaExtemplatescript ivrLibaExtemplatescript : ivrLibaExtemplatescripts) {
                            Matcher matcher = null;
                            if (StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex())) {
                                Pattern pattern = Pattern.compile(ivrLibaExtemplatescript.getSelfRegex());
                                matcher = pattern.matcher(questionMessage.getContent());
                            }
                            Matcher matcher2 = null;
                            if (StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex2())) {
                                Pattern pattern2 = Pattern.compile(ivrLibaExtemplatescript.getSelfRegex2());
                                matcher2 = pattern2.matcher(questionMessage.getContent());
                            }
                            log.info("++++++++++++++++++++++++++通用库是否为空:selfRegex : {} , selfRegex2 : {}", ivrLibaExtemplatescript.getSelfRegex(), ivrLibaExtemplatescript.getSelfRegex2());
                            if (StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex()) && matcher.matches() && StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex2()) && matcher2.matches() || StringUtils.isEmpty(ivrLibaExtemplatescript.getSelfRegex()) && StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex2()) && matcher2.matches() || StringUtils.isEmpty(ivrLibaExtemplatescript.getSelfRegex2()) && StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex()) && matcher.matches()) {
                                QuestionMessage returnQues = redisCache.getCacheObject(userId + "returnQues");
                                IvrLibaTemplateScriptVO nowQuestion = returnQues.getNowQuestion();
                                nowQuestion.setSubmoduleText(ivrLibaExtemplatescript.getSwitchText());
                                nowQuestion.setSubmoduleVoice(ivrLibaExtemplatescript.getSwitchWav());
                                redisCache.setCacheObject(userId + "returnQues", returnQues, 120, TimeUnit.MINUTES);
                                if (ivrLibaExtemplatescript.getIsEnd() == 1) {
                                    //将问题置空
                                    IvrLibaTemplateScriptVO nowQuestion1 = returnQues.getNowQuestion();
                                    nowQuestion1.setQuestionText(null);
                                    nowQuestion1.setQuestionVoice(null);
                                    returnQues.setNowQuestion(nowQuestion1);
                                    redisCache.setCacheObject(userId + "returnQues", returnQues, 120, TimeUnit.MINUTES);
                                    redisCache.setCacheObject(userId + "isOver", 1, 120, TimeUnit.MINUTES);
                                }
                            }
                            break;
                        }
                    }
                }
            }
            QuestionMessage returnQues = redisCache.getCacheObject(userId + "returnQues");
            List<IvrLibaTemplateScriptVO> backQusetRedis = redisCache.getCacheObject(userId + "backQuset");
            returnQues.setQuestionList(backQusetRedis);
            session.sendMessage(new TextMessage(JSON.toJSONString(returnQues).getBytes(StandardCharsets.UTF_8)));
            //整个流程是否结束,将redis中的该userId下的数据删除;
            Integer isOver = redisCache.getCacheObject(userId + "isOver");
            if (isOver == 1) {
                redisCache.deleteObject(userId + "ivrLibaTemplateScriptVOList");
                redisCache.deleteObject(userId + "backQuset");
                redisCache.deleteObject(userId + "noVoice");
                redisCache.deleteObject(userId + "returnQues");
                redisCache.deleteObject(userId + "isOver");
                redisCache.deleteObject(userId + "ivrLibaTemplateVO1");
                try {
                    //断开链接
                    afterConnectionClosed(session, null);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    //获取下一题(这个方法不适合选项中的nextQuestion)
    private QuestionMessage getNextQuestion(List<IvrLibaTemplateScriptVO> ivrLibaTemplateScriptVOList, IvrLibaTemplateScriptVO ivrLibaTemplateScriptVO) {
        QuestionMessage returnQues = new QuestionMessage();
        for (int j = 0; j < ivrLibaTemplateScriptVOList.size(); j++) {
            if (ivrLibaTemplateScriptVOList.get(j).getTargetid() == ivrLibaTemplateScriptVO.getTargetid() + 1) {
                // å¯¹è¯¥æ¡templateScriptVO进行处理
                returnQues.setNowQuestion(ivrLibaTemplateScriptVOList.get(j));
            }
        }
        return returnQues;
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/IvrLibaExtemplateController.java
@@ -73,7 +73,7 @@
    @Log(title = "通过模板", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    public AjaxResult add(@RequestBody IvrLibaExtemplate ivrLibaExtemplate) {
        return toAjax(ivrLibaExtemplateService.insertIvrLibaExtemplate(ivrLibaExtemplate));
        return AjaxResult.success(ivrLibaExtemplateService.insertIvrLibaExtemplate(ivrLibaExtemplate));
    }
    /**
@@ -94,7 +94,7 @@
    @PreAuthorize("@ss.hasPermi('smartor:extemplate:remove')")
    @Log(title = "通过模板", businessType = BusinessType.DELETE)
    @GetMapping("/remove/{IDs}")
    public AjaxResult remove(@PathVariable String[] IDs) {
    public AjaxResult remove(@PathVariable Long[] IDs) {
        return toAjax(ivrLibaExtemplateService.deleteIvrLibaExtemplateByIDs(IDs));
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/IvrLibaExtemplatescriptController.java
@@ -94,7 +94,7 @@
    @PreAuthorize("@ss.hasPermi('smartor:extemplatescript:remove')")
    @Log(title = "通用模板话术", businessType = BusinessType.DELETE)
    @GetMapping("/remove/{IDs}")
    public AjaxResult remove(@PathVariable String[] IDs) {
    public AjaxResult remove(@PathVariable Long[] IDs) {
        return toAjax(ivrLibaExtemplatescriptService.deleteIvrLibaExtemplatescriptByIDs(IDs));
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/IvrLibaTemplateController.java
@@ -7,12 +7,18 @@
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.smartor.config.RabbitMqConfig;
import com.smartor.domain.IvrLibaTemplate;
import com.smartor.domain.IvrLibaTemplateVO;
import com.smartor.service.IIvrLibaTemplateService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
@@ -26,12 +32,16 @@
 * @author ruoyi
 * @date 2023-12-23
 */
@Slf4j
@Api(description = "随访模板库")
@RestController
@RequestMapping("/smartor/template")
public class IvrLibaTemplateController extends BaseController {
    @Autowired
    private IIvrLibaTemplateService ivrLibaTemplateService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * æŸ¥è¯¢æ¨¡æ¿åº“列表
@@ -105,7 +115,6 @@
     * æ–°å¢žæˆ–修改随访模板库详情
     */
    @ApiOperation("新增或修改随访模板库详情")
    @PreAuthorize("@ss.hasPermi('smartor:script:list')")
    @PostMapping("/saveOrUpdateScript")
    public AjaxResult saveOrUpdateScript(@RequestBody IvrLibaTemplateVO ivrLibaTemplateVO) {
        if (ObjectUtils.isEmpty(ivrLibaTemplateVO)) {
@@ -125,4 +134,34 @@
        }
        return success(ivrLibaTemplateService.selectInfoByCondition(ivrLibaTemplateVO));
    }
    /**
     * å¼€å§‹æ‰§è¡Œ(测试用)
     */
    @GetMapping("/queryRabbitmq")
    public AjaxResult queryRabbitmq(@RequestParam("routintKey") String routintKey, @RequestParam("content") String content, @RequestParam("times") Long times) {
//        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_NAME, "phone.001", "测试数据001");
//        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_NAME, "phone.002", "测试数据002");
//        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_NAME, "phone.003", "测试数据003");
//        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_NAME, routintKey, message, new MessagePostProcessor() {
//            @Override
//            public Message postProcessMessage(Message message) throws AmqpException {
////                message.getMessageProperties().setDelay(times);
//                message.getMessageProperties().getHeaders().put("x-delay", times);
////message.getMessageProperties().setExpiration();
//                return message;
//            }
//        });
        log.info("-------------启动咨询应答超时提醒延迟队列-------------");
        this.rabbitTemplate.convertAndSend(RabbitMqConfig.phone_exchange, RabbitMqConfig.routing_key, content, message -> {
            //注意这里时间可以使long,而且是设置header
            message.getMessageProperties().setHeader("x-delay", times);
            return message;
        });
        log.info("-------------延迟队列{}ms后执行.-------------", times);
        return success();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/IvrTaskcallController.java
@@ -1,15 +1,19 @@
package com.ruoyi.web.controller.smartor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DtoConversionUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.smartor.domain.HeTaskVO;
import com.smartor.domain.IvrTaskcall;
import com.smartor.domain.IvrTaskcallVO;
import com.smartor.domain.*;
import com.smartor.service.IIvrTaskcallService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -18,7 +22,9 @@
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * å•一任务(随访)Controller
@@ -26,7 +32,7 @@
 * @author ruoyi
 * @date 2024-02-02
 */
@Api(description = "单一任务(随访)")
@Api(description = "单一任务(随访宣教)")
@RestController
@RequestMapping("/smartor/taskcall")
public class IvrTaskcallController extends BaseController {
@@ -36,7 +42,7 @@
    /**
     * æŸ¥è¯¢å•一任务(随访)列表
     */
    @ApiOperation("查询单一任务(随访)列表")
    @ApiOperation("查询单一任务(随访宣教)列表")
    @PreAuthorize("@ss.hasPermi('system:taskcall:list')")
    @PostMapping("/list")
    public TableDataInfo list(@RequestBody IvrTaskcall ivrTaskcall) {
@@ -46,10 +52,10 @@
    }
    /**
     * å¯¼å‡ºå•一任务(随访)列表
     * å¯¼å‡ºå•一任务(随访宣教)列表
     */
    @PreAuthorize("@ss.hasPermi('system:taskcall:export')")
    @Log(title = "单一任务(随访)", businessType = BusinessType.EXPORT)
    @Log(title = "单一任务(随访宣教)", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, IvrTaskcall ivrTaskcall) {
        List<IvrTaskcall> list = ivrTaskcallService.selectIvrTaskcallList(ivrTaskcall);
@@ -78,5 +84,72 @@
    }
    /**
     * æ ¹æ®æ¡ä»¶æŸ¥è¯¢ä»»åŠ¡ä¿¡æ¯
     */
    @ApiOperation("根据条件查询任务信息")
    @PostMapping("/queryTaskByCondition")
    public AjaxResult queryTaskByCondition(@RequestBody IvrTaskcallVO ivrTaskcallVO) {
        //根据入参查询信息
        IvrTaskcall ivrTaskcall = DtoConversionUtils.sourceToTarget(ivrTaskcallVO, IvrTaskcall.class);
        List<IvrTaskcall> list = ivrTaskcallService.selectIvrTaskcallList(ivrTaskcall);
        //定义患者与单一任务关联表集合
        List<PatTaskRelevance> patTaskRelevances = new ArrayList<>();
        //将查出来的数据倒入IvrTaskcallVO中
        IvrTaskcallVO ivrTaskcallVO2 = DtoConversionUtils.sourceToTarget(list.get(0), IvrTaskcallVO.class);
        String sendTimeSlot = list.get(0).getSendTimeSlot();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            //获取到发送时间的集合
            if (StringUtils.isNotEmpty(sendTimeSlot)) {
                List<TaskSendTimeVO> taskSendTimeVOList = objectMapper.readValue(sendTimeSlot, List.class);
                ivrTaskcallVO2.setSendTimeslot(taskSendTimeVOList);
            }
            //文本变量参数
            if (StringUtils.isNotEmpty(list.get(0).getTextParam())) {
                Map<String, Map<String, String>> textParam = objectMapper.readValue(list.get(0).getTextParam(), Map.class);
                ivrTaskcallVO2.setTextParam(textParam);
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        for (IvrTaskcall ivrTaskcall1 : list) {
            PatTaskRelevance patTaskRelevance = new PatTaskRelevance();
            //获取到患者信息,并放入到集合中
            patTaskRelevance.setName(ivrTaskcall1.getSendname());
            patTaskRelevance.setAge(ivrTaskcall1.getAge());
            patTaskRelevance.setSfzh(ivrTaskcall1.getSfzh());
            patTaskRelevance.setPhone(ivrTaskcall1.getPhone());
            patTaskRelevance.setAddr(ivrTaskcall1.getAddr());
            patTaskRelevances.add(patTaskRelevance);
        }
        ivrTaskcallVO2.setPatTaskRelevances(patTaskRelevances);
        return success(ivrTaskcallVO2);
    }
    /**
     * ä»»åŠ¡å‘é€æ‰§è¡Œ
     */
    @ApiOperation("任务发送执行")
    @PostMapping("/heTaskSend")
    public AjaxResult heTaskSend(@RequestBody IvrTaskcallVO ivrTaskcallVO) {
        return toAjax(ivrTaskcallService.heTaskSend(ivrTaskcallVO));
    }
    /**
     * ç”µè¯å›žè°ƒä»»åŠ¡
     */
    @ApiOperation("电话回调任务")
    @PostMapping("/phoneCallBack")
    public AjaxResult phoneCallBack(@RequestBody PhoneCallBackVO phoneCallBackVO) {
        //如果uuid在redis中找不到,那就直接报异常
        return success(ivrTaskcallService.phoneCallBack(phoneCallBackVO));
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/tools/PersonVoiceController.java
@@ -1,46 +1,15 @@
package com.ruoyi.web.controller.smartor.tools;
import afu.org.checkerframework.checker.oigj.qual.O;
import com.alibaba.nls.client.AccessToken;
import com.alibaba.nls.client.protocol.NlsClient;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.smartor.domain.BaseSmsRequest;
import com.smartor.domain.BaseSmsaccount;
import com.smartor.domain.BatchBaseSmsRequest;
import com.smartor.domain.TemplateSmsRequest;
import com.smartor.service.DingTalkService;
import com.smartor.service.IBaseSmsaccountService;
import com.smartor.service.PersonVoiceService;
import com.taobao.api.ApiException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@@ -49,7 +18,7 @@
 * @author ls
 * @date 2023-11-17
 */
@Api(description = "人工语音")
@Api(description = "语音合成转换")
@RestController
@RequestMapping("/smartor/voice")
public class PersonVoiceController extends BaseController {
@@ -66,8 +35,8 @@
    @ApiOperation("文字转语音")
    @GetMapping("/texttospeech")
    public Map<String, Object> texttospeech(@RequestParam("textspeech") String textspeech) {
        String recognizerListener = personVoiceService.texttospeech(textspeech);
    public Map<String, Object> texttospeech(@RequestParam("textspeech") String textspeech, @RequestParam("filePath") String filePath) {
        String recognizerListener = personVoiceService.texttospeech(textspeech, filePath);
        return success(recognizerListener);
    }
ruoyi-admin/src/main/java/com/ruoyi/web/task/PhoneTask.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
package com.ruoyi.web.task;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.smartor.config.PhoneUtils;
import com.smartor.domain.IvrLibaTemplateScriptVO;
import com.smartor.domain.IvrLibaTemplateVO;
import com.smartor.domain.IvrTaskcall;
import com.smartor.domain.QuestionMessage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class PhoneTask implements Runnable {
    private IvrTaskcall ivrTaskcall;
    private List<IvrLibaTemplateScriptVO> ivrLibaTemplateScriptVO;
    private RedisCache redisCache;
    private IvrLibaTemplateVO ivrLibaTemplateVO;
    public PhoneTask(IvrTaskcall ivrTaskcall, IvrLibaTemplateVO ivrLibaTemplateVO, RedisCache redisCache) {
        this.ivrTaskcall = ivrTaskcall;
        this.ivrLibaTemplateScriptVO = ivrLibaTemplateVO.getIvrLibaTemplateScriptVOList();
        this.ivrLibaTemplateVO = ivrLibaTemplateVO;
        this.redisCache = redisCache;
    }
    @Override
    public void run() {
        //获取电话组,查看哪些电话可以使用
        PhoneUtils phoneUtils = new PhoneUtils();
        String uuid = IdUtils.randomUUID();
        Map<String, Object> objectMap = new HashMap<>();
        objectMap.put("ivrTaskcall", ivrTaskcall);
        objectMap.put("ivrLibaTemplateScriptVO", ivrLibaTemplateScriptVO);
        //将数据放到redis中,方便在回调方法里获取
        redisCache.setCacheObject(uuid, objectMap, 120, TimeUnit.MINUTES);
        //记录首次问题
        QuestionMessage returnQues = new QuestionMessage();
        returnQues.setKcb(ivrLibaTemplateVO.getRevisitBefore());
        for (IvrLibaTemplateScriptVO ivrLibaTemplateScriptVO : ivrLibaTemplateScriptVO) {
            if (ivrLibaTemplateScriptVO.getTargetid() == ivrLibaTemplateVO.getFirstQuestionNum().intValue()) {
                returnQues.setNowQuestion(ivrLibaTemplateScriptVO);
            }
        }
        returnQues.setQuestionList(ivrLibaTemplateScriptVO);
        //将问题,和模板信息放到redis中
        redisCache.setCacheObject(uuid + "returnQues", returnQues, 120, TimeUnit.MINUTES);
        redisCache.setCacheObject(uuid + "ivrLibaTemplateVO", ivrLibaTemplateVO, 120, TimeUnit.MINUTES);
        //调用机器人电话,开始电话(需要将回调方法传入,这个等”电话方“告诉怎么传,现在先空着,还有第一句问题话术)
        phoneUtils.ob(uuid, null, ivrTaskcall.getPhone(), null, null, null, null, null, null, null, null);
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/test/MQTest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.web.test;
import com.smartor.config.RabbitMqConfig;
import org.junit.Test;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
//@SpringBootTest
//@RunWith(SpringRunner.class)
public class MQTest {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Test
    public void testSend() {
//        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_NAME, "phone.001", "测试数据001");
//        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_NAME, "phone.002", "测试数据002");
//        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_NAME, "phone.003", "测试数据003");
    }
}
ruoyi-admin/src/main/resources/application-druid.yml
@@ -1,26 +1,49 @@
# æ•°æ®æºé…ç½®
spring:
  rabbitmq:
    host: 116.62.18.175
    password: guest
    port: 5672
    username: guest
    virtual-host: /
     # å¼€å¯æ¶ˆæ¯å‘送确认
    publisher-confirms: true
    publisher-returns: true
    listener:
      simple:
        acknowledge-mode: manual
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    #    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        #        ä¹‰ä¹ŒäºŒé™¢
        #        url: jdbc:mysql://127.0.0.1:3306/smartor?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        #        username: root
        #        password: 123456
        #        å…¬å¸
        url: jdbc:mysql://116.62.18.175:6002/smartor?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: hxsoft
        password: Hxerp2000
        driverClassName: com.mysql.cj.jdbc.Driver
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭(公司)
        enabled: true
        url: jdbc:sqlserver://116.62.18.175:6001;DatabaseName=iv-ywey;encrypt=false;SelectMethod=cursor
        username: sa
        password: Hxerp2000
        driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭(义乌二院)
      #        enabled: true
      #        url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=IntelligentVoice;encrypt=false;SelectMethod=cursor
      #        username: sa
      #        password: sfxt#2023
      #        driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
@@ -94,3 +117,6 @@
accessKeyId: LTAI4G5zjJRkun2eRdzU8GhR
accessKeySecret: 6EIRr9uZeRobvHBRqskyGwjTLKpHYv
signName: æ­å·žåˆ©æ¹–科技
#智能呼叫
phoneIP: http://124.220.50.51:8001
ruoyi-admin/src/main/resources/application.yml
@@ -71,13 +71,13 @@
      enabled: true
  # redis é…ç½®
  redis:
    # åœ°å€
    #    # åœ°å€ï¼ˆä¹‰ä¹ŒäºŒé™¢ï¼‰
#    host: 127.0.0.1
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
#    port: 6379
#    # åœ°å€
    #    port: 6020
    # åœ°å€ï¼ˆå…¬å¸ï¼‰
    host: 116.62.18.175
#    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6020
    # æ•°æ®åº“索引
    database: 0
ruoyi-admin/src/main/resources/logback.xml
@@ -22,8 +22,8 @@
            <!-- æ—¥å¿—最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        <encoder>l
            <pattern>${og.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- è¿‡æ»¤çš„级别 -->
ruoyi-common/pom.xml
@@ -186,6 +186,17 @@
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.41</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
ruoyi-common/src/main/java/com/ruoyi/common/exception/HttpRequestException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.ruoyi.common.exception;
public class HttpRequestException extends RuntimeException {
    private static final long serialVersionUID = 1158312384059617619L;
    private int code;
    public HttpRequestException() {
        super();
    }
    public HttpRequestException(int code, Throwable cause) {
        super(cause);
        this.code = code;
    }
    public HttpRequestException(int code, String message) {
        super(message);
        this.code = code;
    }
    public int getCode() {
        return code;
    }
    public String getMsg() {
        return super.getMessage();
    }
    @Override
    public String getMessage() {
        return "Error code is " + code + ", msg is " + super.getMessage();
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java
@@ -3,12 +3,9 @@
import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.*;
import java.util.Date;
import org.apache.commons.lang3.time.DateFormatUtils;
/**
@@ -16,8 +13,7 @@
 * 
 * @author ruoyi
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils
{
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
    public static String YYYY = "yyyy";
    public static String YYYY_MM = "yyyy-MM";
@@ -28,18 +24,14 @@
    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
    private static String[] parsePatterns = {"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
    /**
     * èŽ·å–å½“å‰Date型日期
     * 
     * @return Date() å½“前日期
     */
    public static Date getNowDate()
    {
    public static Date getNowDate() {
        return new Date();
    }
@@ -48,44 +40,34 @@
     * 
     * @return String
     */
    public static String getDate()
    {
    public static String getDate() {
        return dateTimeNow(YYYY_MM_DD);
    }
    public static final String getTime()
    {
    public static final String getTime() {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }
    public static final String dateTimeNow()
    {
    public static final String dateTimeNow() {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }
    public static final String dateTimeNow(final String format)
    {
    public static final String dateTimeNow(final String format) {
        return parseDateToStr(format, new Date());
    }
    public static final String dateTime(final Date date)
    {
    public static final String dateTime(final Date date) {
        return parseDateToStr(YYYY_MM_DD, date);
    }
    public static final String parseDateToStr(final String format, final Date date)
    {
    public static final String parseDateToStr(final String format, final Date date) {
        return new SimpleDateFormat(format).format(date);
    }
    public static final Date dateTime(final String format, final String ts)
    {
        try
        {
    public static final Date dateTime(final String format, final String ts) {
        try {
            return new SimpleDateFormat(format).parse(ts);
        }
        catch (ParseException e)
        {
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
@@ -93,8 +75,7 @@
    /**
     * æ—¥æœŸè·¯å¾„ å³å¹´/月/日 å¦‚2018/08/08
     */
    public static final String datePath()
    {
    public static final String datePath() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }
@@ -102,8 +83,7 @@
    /**
     * æ—¥æœŸè·¯å¾„ å³å¹´/月/日 å¦‚20180808
     */
    public static final String dateTime()
    {
    public static final String dateTime() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }
@@ -111,18 +91,13 @@
    /**
     * æ—¥æœŸåž‹å­—符串转化为日期 æ ¼å¼
     */
    public static Date parseDate(Object str)
    {
        if (str == null)
        {
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try
        {
        try {
            return parseDate(str.toString(), parsePatterns);
        }
        catch (ParseException e)
        {
        } catch (ParseException e) {
            return null;
        }
    }
@@ -130,8 +105,7 @@
    /**
     * èŽ·å–æœåŠ¡å™¨å¯åŠ¨æ—¶é—´
     */
    public static Date getServerStartDate()
    {
    public static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }
@@ -139,16 +113,14 @@
    /**
     * è®¡ç®—相差天数
     */
    public static int differentDaysByMillisecond(Date date1, Date date2)
    {
    public static int differentDaysByMillisecond(Date date1, Date date2) {
        return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
    }
    /**
     * è®¡ç®—两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate)
    {
    public static String getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
@@ -169,8 +141,7 @@
    /**
     * å¢žåŠ  LocalDateTime ==> Date
     */
    public static Date toDate(LocalDateTime temporalAccessor)
    {
    public static Date toDate(LocalDateTime temporalAccessor) {
        ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }
@@ -178,10 +149,29 @@
    /**
     * å¢žåŠ  LocalDate ==> Date
     */
    public static Date toDate(LocalDate temporalAccessor)
    {
    public static Date toDate(LocalDate temporalAccessor) {
        LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }
    /**
     * å¾€å‰æŽ¨å¤šå°‘分钟,获取往前推的时间点
     *
     * @param minute     åˆ†é’Ÿ
     * @param timeFormat æ—¶é—´æ ¼å¼
     * @return
     */
    public static String beforeTime(Long minute, String timeFormat) {
        if (StringUtils.isEmpty(timeFormat)) {
            timeFormat = YYYY_MM_DD_HH_MM_SS;
        }
        LocalDateTime now = LocalDateTime.now();
        Duration tenMinutes = Duration.ofMinutes(minute);
        LocalDateTime tenMinutesAgo = now.minus(tenMinutes);
        Date date = Date.from(tenMinutesAgo.atZone(ZoneOffset.ofHours(8)).toInstant());
        SimpleDateFormat dateFormat = new SimpleDateFormat(timeFormat);//可以方便地修改日期格式
        String nowTime_10 = dateFormat.format(date);
        return nowTime_10;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,358 @@
package com.ruoyi.common.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.util.StringUtil;
import com.ruoyi.common.exception.HttpRequestException;
import com.ruoyi.common.utils.http.HttpEntity;
import com.ruoyi.common.utils.json.JsonRequestBody;
import com.ruoyi.common.utils.json.JsonResponseBody;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.Charsets;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
public class HttpUtil {
    protected static final int DEFAULT_STATUS_ERROR_CODE = 100001;//默认http异常状态码
    protected static final String CONTENT_TYPE = "Content-Type";
    protected static final String APPLICATION_JSON = "application/json";
    protected static final String APPLICATION_JSON_UTF8 = "application/json; charset=utf-8";
    protected static final String TEXT_XML = "text/xml";
    protected static final String TEXT_XML_UTF8 = "text/xml; charset=utf-8";
    protected static final int OK = 200;
    /**
     * ç©ºçš„æŠ¥æ–‡å¤´
     */
    protected static final Map<String, String> EMPTY_HEADERS = new HashMap<String, String>(0);
    /**
     * ç¼–码错误
     */
    protected static final int ENCODING_ERROR_CODE = 999997;
    /**
     * HTTP é”™è¯¯: æ­»é”ã€æ–‡ä»¶è¿‡å¤§ç­‰æ–‡ä»¶
     */
    protected static final int HTTP_ERROR_CODE = 999996;
    /**
     * IO é”™è¯¯
     */
    protected static final int IO_ERROR_CODE = 999995;
    /**
     * å“åº”为null
     */
    protected static final int RESPONSE_NULL_ERROR_CODE = 999994;
    protected static final String USER_IP_KEY = "x-remoteip";
    protected static final String TEXT_NORMAL = "application/x-www-form-urlencoded; charset=utf-8";
    protected static final HttpClient httpClient = getHttpClient();
    private static final SimpleDateFormat formatHttpData = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
    private static HttpClient getHttpClient() {
        // æ­¤å¤„运用连接池技术。
        MultiThreadedHttpConnectionManager manager = new MultiThreadedHttpConnectionManager();
        // è®¾å®šå‚数:与每个主机的最大连接数
        manager.getParams().setDefaultMaxConnectionsPerHost(100);
        // è®¾å®šå‚数:客户端的总连接数
        manager.getParams().setMaxTotalConnections(400);
        // è®¾ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´,单位:毫秒
        manager.getParams().setConnectionTimeout(8000);
        // è®¾ç½®è¯·æ±‚读取超时时间,单位:毫秒
        manager.getParams().setSoTimeout(8000);
        // è®¾ç½®ä»Žè¿žæŽ¥æ± ä¸­èŽ·å–é“¾æŽ¥æ—¶é—´ï¼Œ å•位:毫秒
        manager.getParams().setParameter(HttpClientParams.CONNECTION_MANAGER_TIMEOUT, 8000);
        // ä½¿ç”¨è¿žæŽ¥æ± æŠ€æœ¯åˆ›å»ºHttpClient对象
        HttpClient httpClient = new HttpClient(manager);
        return httpClient;
    }
    public static String postJsonRequest(String url, String request) throws HttpRequestException {
        Assert.hasLength(url, "请求url不能为空字符串。");
        EntityEnclosingMethod httpMethod = new PostMethod(url);
        httpMethod.addRequestHeader("Content-Type", "application/json; charset=UTF-8");
        setHeaderRequestId(httpMethod);
        try {
            RequestEntity entity = new StringRequestEntity(request, "application/json", "utf-8");
            httpMethod.setRequestEntity(entity);
            int resultCode = httpClient.executeMethod(httpMethod);
            InputStream inputStream = httpMethod.getResponseBodyAsStream();
            if (inputStream == null) {
                throw new HttpRequestException(RESPONSE_NULL_ERROR_CODE, "响应为null");
            }
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuffer stringBuffer = new StringBuffer();
            String str = "";
            while ((str = reader.readLine()) != null) {
                stringBuffer.append(str);
            }
            reader.close();
            String respJson = stringBuffer.toString();
            // String respJson = httpMethod.getResponseBodyAsString();
            if (resultCode == OK) {
                return respJson;
            } else {
                throw new HttpRequestException(resultCode, respJson);
            }
        } catch (UnsupportedEncodingException e) {
            throw new HttpRequestException(ENCODING_ERROR_CODE, e);
        } catch (HttpException e) {
            throw new HttpRequestException(HTTP_ERROR_CODE, e);
        } catch (IOException e) {
            throw new HttpRequestException(IO_ERROR_CODE, e);
        } finally {
            if (httpMethod != null) {
                httpMethod.releaseConnection();
            }
        }
    }
    /**
     * json的post请求
     *
     * @param url           è¯·æ±‚url
     * @param reqEntity     è¯·æ±‚头与请求体的封装
     * @param respBodyClass å“åº”体类型
     * @return è¿”回的响应结果
     */
    @SuppressWarnings("unchecked")
    public static <RESPBODY> HttpEntity<RESPBODY> postJsonRequestV2(String url, HttpEntity<?> reqEntity, Class<RESPBODY> respBodyClass) {
        Assert.hasLength(url, "请求url不能为空字符串。");
        Assert.notNull(reqEntity, "请求request不能为null。");
        Assert.notNull(reqEntity.getBody(), "Post请求body不能为null。");
        EntityEnclosingMethod httpMethod = new PostMethod(url);
        //设置header信息
        Map<String, String> headers = reqEntity.getHeaders();
        //若传入报文头,则设置值
        if (headers != HttpEntity.EMPTY_HEADERS) {
            setReqHeaders(headers, httpMethod);
        }
        //设置body信息
        String reqJson = JSON.toJSONString(reqEntity.getBody());
        String charset = com.google.common.base.Charsets.UTF_8.name();
        // å‘送含xml消息体的对象
        try {
            RequestEntity entity = new StringRequestEntity(reqJson, APPLICATION_JSON, charset);
            httpMethod.setRequestEntity(entity);
            // æ‰§è¡Œè¯·æ±‚并接收响应码
            int resultCode = httpClient.executeMethod(httpMethod);
            InputStream inputStream = httpMethod.getResponseBodyAsStream();
            if (inputStream == null) {
                throw new HttpRequestException(RESPONSE_NULL_ERROR_CODE, "响应为null");
            }
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuffer stringBuffer = new StringBuffer();
            String str = "";
            while ((str = reader.readLine()) != null) {
                stringBuffer.append(str);
            }
            reader.close();
            String respStr = stringBuffer.toString();
            //String respStr = httpMethod.getResponseBodyAsString();
            if (resultCode == OK) {
                //响应头
                Map<String, String> respHeaders = getRespHeaders(httpMethod);
                //响应体
                HttpEntity<RESPBODY> rep = null;
                if (isNullOrEmpty(respStr) || null == respBodyClass) {
                    rep = new HttpEntity<RESPBODY>(respHeaders, null);
                    ;// æ— å“åº”
                } else {
                    if (respBodyClass != String.class) {
                        RESPBODY respBody = JSON.parseObject(respStr, respBodyClass);
                        rep = new HttpEntity<RESPBODY>(respHeaders, respBody);
                    } else {
                        rep = new HttpEntity<RESPBODY>(respHeaders, (RESPBODY) respStr);
                    }
                }
                return rep;
            } else if (resultCode == DEFAULT_STATUS_ERROR_CODE) {
                JSONObject model = JSON.parseObject(respStr);
                throw new HttpRequestException(model.getIntValue("code"), model.getString("msg"));
            } else {
                throw new HttpRequestException(resultCode, respStr);
            }
        } catch (UnsupportedEncodingException e) {
            throw new HttpRequestException(ENCODING_ERROR_CODE, e);
        } catch (HttpException e) {
            throw new HttpRequestException(HTTP_ERROR_CODE, e);
        } catch (IOException e) {
            throw new HttpRequestException(IO_ERROR_CODE, e);
        } finally {
            if (httpMethod != null) {
                httpMethod.releaseConnection();
            }
        }
    }
    public static <RESPBODY extends JsonResponseBody> HttpEntity<RESPBODY> postJsonRequest(String url, HttpEntity<? extends JsonRequestBody> reqEntity, Class<RESPBODY> respBodyClass) {
        Assert.hasLength(url, "请求url不能为空字符串。");
        Assert.notNull(reqEntity, "请求request不能为null。");
        Assert.notNull(reqEntity.getBody(), "Post请求body不能为null。");
        EntityEnclosingMethod httpMethod = new PostMethod(url);
        //设置header信息
        Map<String, String> headers = reqEntity.getHeaders();
        //若传入报文头,则设置值
        if (headers != HttpEntity.EMPTY_HEADERS) {
            setReqHeaders(headers, httpMethod);
        }
        //设置body信息
        String reqJson = JSON.toJSONString(reqEntity.getBody());
        String charset = Charsets.UTF_8.name();
        // å‘送含xml消息体的对象
        try {
            RequestEntity entity = new StringRequestEntity(reqJson, APPLICATION_JSON, charset);
            httpMethod.setRequestEntity(entity);
            // æ‰§è¡Œè¯·æ±‚并接收响应码
            int resultCode = httpClient.executeMethod(httpMethod);
            InputStream inputStream = httpMethod.getResponseBodyAsStream();
            if (inputStream == null) {
                throw new HttpRequestException(RESPONSE_NULL_ERROR_CODE, "响应为null");
            }
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuffer stringBuffer = new StringBuffer();
            String str = "";
            while ((str = reader.readLine()) != null) {
                stringBuffer.append(str);
            }
            reader.close();
            String respStr = stringBuffer.toString();
            if (resultCode == OK) {
                //响应头
                Map<String, String> respHeaders = getRespHeaders(httpMethod);
                //响应体
                HttpEntity<RESPBODY> rep = null;
                if (isNullOrEmpty(respStr) || null == respBodyClass) {
                    rep = new HttpEntity<RESPBODY>(respHeaders, null);
                    ;// æ— å“åº”
                } else {
                    RESPBODY respBody = JSON.parseObject(respStr, respBodyClass);
                    rep = new HttpEntity<RESPBODY>(respHeaders, respBody);
                }
                return rep;
            } else if (resultCode == DEFAULT_STATUS_ERROR_CODE) {
                JSONObject model = JSON.parseObject(respStr);
                throw new HttpRequestException(model.getIntValue("code"), model.getString("msg"));
            } else {
                throw new HttpRequestException(resultCode, respStr);
            }
        } catch (UnsupportedEncodingException e) {
            throw new HttpRequestException(ENCODING_ERROR_CODE, e);
        } catch (HttpException e) {
            throw new HttpRequestException(HTTP_ERROR_CODE, e);
        } catch (IOException e) {
            throw new HttpRequestException(IO_ERROR_CODE, e);
        } finally {
            if (httpMethod != null) {
                httpMethod.releaseConnection();
            }
        }
    }
    public static String postFormRequest(String url, Map<String, String> params) throws HttpRequestException {
        Assert.hasLength(url, "请求url不能为空字符串。");
        Assert.notNull(params, "请求params不能为空。");
        PostMethod httpMethod = new PostMethod(url);
        httpMethod.addRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        try {
            // å‘送请求参数
            StringBuilder param = new StringBuilder();
            for (Map.Entry<String, String> entry : params.entrySet()) {
                if (param.length() > 0) {
                    param.append("&");
                }
                param.append(entry.getKey());
                param.append("=");
                param.append(entry.getValue());
            }
            RequestEntity entity = new StringRequestEntity(param.toString(), "application/json", "utf-8");
            httpMethod.setRequestEntity(entity);
            // æ‰§è¡Œè¯·æ±‚并接收响应码
            int resultCode = httpClient.executeMethod(httpMethod);
            String respJson = httpMethod.getResponseBodyAsString();
            if (resultCode == OK) {
                return respJson;
            } else {
                throw new HttpRequestException(resultCode, respJson);
            }
        } catch (UnsupportedEncodingException e) {
            throw new HttpRequestException(ENCODING_ERROR_CODE, e);
        } catch (HttpException e) {
            throw new HttpRequestException(HTTP_ERROR_CODE, e);
        } catch (IOException e) {
            throw new HttpRequestException(IO_ERROR_CODE, e);
        } finally {
            if (httpMethod != null) {
                httpMethod.releaseConnection();
            }
        }
    }
    private static Map<String, String> getRespHeaders(HttpMethodBase httpMethod) {
        //得到响应头
        Header[] respHeaders = httpMethod.getResponseHeaders();
        Map<String, String> headers = new HashMap<String, String>(respHeaders.length);
        for (Header header : respHeaders)
            headers.put(header.getName(), header.getValue());
        return headers;
    }
    protected static void setReqHeaders(Map<String, String> headers, HttpMethodBase httpMethod) {
        //设置请求头
        for (Map.Entry<String, String> header : headers.entrySet()) {
            httpMethod.addRequestHeader(header.getKey(), header.getValue());
        }
    }
    protected static void setHeaderRequestId(HttpMethodBase httpMethod) {
        //设置请求头
        ServletRequestAttributes req = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (null != req) {
            String requestId = req.getRequest().getHeader("x-request-id");
            if (StringUtil.isNotEmpty(requestId)) {
                httpMethod.addRequestHeader("x-request-id", requestId);
                log.info("header中x-request-id值为:{}", requestId);
            }
        }
    }
    private static boolean isNullOrEmpty(String obj) {
        if (obj == null || obj.isEmpty()) {
            return true;
        }
        return false;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
@@ -11,6 +11,7 @@
import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import com.ruoyi.common.config.RuoYiConfig;
@@ -24,8 +25,7 @@
 * 
 * @author ruoyi
 */
public class FileUtils
{
public class FileUtils {
    public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
    /**
@@ -35,30 +35,22 @@
     * @param os è¾“出流
     * @return
     */
    public static void writeBytes(String filePath, OutputStream os) throws IOException
    {
    public static void writeBytes(String filePath, OutputStream os) throws IOException {
        FileInputStream fis = null;
        try
        {
        try {
            File file = new File(filePath);
            if (!file.exists())
            {
            if (!file.exists()) {
                throw new FileNotFoundException(filePath);
            }
            fis = new FileInputStream(file);
            byte[] b = new byte[1024];
            int length;
            while ((length = fis.read(b)) > 0)
            {
            while ((length = fis.read(b)) > 0) {
                os.write(b, 0, length);
            }
        }
        catch (IOException e)
        {
        } catch (IOException e) {
            throw e;
        }
        finally
        {
        } finally {
            IOUtils.close(os);
            IOUtils.close(fis);
        }
@@ -71,8 +63,7 @@
     * @return ç›®æ ‡æ–‡ä»¶
     * @throws IOException IO异常
     */
    public static String writeImportBytes(byte[] data) throws IOException
    {
    public static String writeImportBytes(byte[] data) throws IOException {
        return writeBytes(data, RuoYiConfig.getImportPath());
    }
@@ -84,20 +75,16 @@
     * @return ç›®æ ‡æ–‡ä»¶
     * @throws IOException IO异常
     */
    public static String writeBytes(byte[] data, String uploadDir) throws IOException
    {
    public static String writeBytes(byte[] data, String uploadDir) throws IOException {
        FileOutputStream fos = null;
        String pathName = "";
        try
        {
        try {
            String extension = getFileExtendName(data);
            pathName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
            File file = FileUploadUtils.getAbsoluteFile(uploadDir, pathName);
            fos = new FileOutputStream(file);
            fos.write(data);
        }
        finally
        {
        } finally {
            IOUtils.close(fos);
        }
        return FileUploadUtils.getPathFileName(uploadDir, pathName);
@@ -109,13 +96,11 @@
     * @param filePath æ–‡ä»¶
     * @return
     */
    public static boolean deleteFile(String filePath)
    {
    public static boolean deleteFile(String filePath) {
        boolean flag = false;
        File file = new File(filePath);
        // è·¯å¾„为文件且不为空则进行删除
        if (file.isFile() && file.exists())
        {
        if (file.isFile() && file.exists()) {
            flag = file.delete();
        }
        return flag;
@@ -127,8 +112,7 @@
     * @param filename æ–‡ä»¶åç§°
     * @return true æ­£å¸¸ false éžæ³•
     */
    public static boolean isValidFilename(String filename)
    {
    public static boolean isValidFilename(String filename) {
        return filename.matches(FILENAME_PATTERN);
    }
@@ -138,17 +122,14 @@
     * @param resource éœ€è¦ä¸‹è½½çš„æ–‡ä»¶
     * @return true æ­£å¸¸ false éžæ³•
     */
    public static boolean checkAllowDownload(String resource)
    {
    public static boolean checkAllowDownload(String resource) {
        // ç¦æ­¢ç›®å½•上跳级别
        if (StringUtils.contains(resource, ".."))
        {
        if (StringUtils.contains(resource, "..")) {
            return false;
        }
        // æ£€æŸ¥å…è®¸ä¸‹è½½çš„æ–‡ä»¶è§„则
        if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
        {
        if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))) {
            return true;
        }
@@ -163,28 +144,20 @@
     * @param fileName æ–‡ä»¶å
     * @return ç¼–码后的文件名
     */
    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
    {
    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException {
        final String agent = request.getHeader("USER-AGENT");
        String filename = fileName;
        if (agent.contains("MSIE"))
        {
        if (agent.contains("MSIE")) {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+", " ");
        }
        else if (agent.contains("Firefox"))
        {
        } else if (agent.contains("Firefox")) {
            // ç«ç‹æµè§ˆå™¨
            filename = new String(fileName.getBytes(), "ISO8859-1");
        }
        else if (agent.contains("Chrome"))
        {
        } else if (agent.contains("Chrome")) {
            // google浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        else
        {
        } else {
            // å…¶å®ƒæµè§ˆå™¨
            filename = URLEncoder.encode(filename, "utf-8");
        }
@@ -197,17 +170,11 @@
     * @param response å“åº”对象
     * @param realFileName çœŸå®žæ–‡ä»¶å
     */
    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
    {
    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException {
        String percentEncodedFileName = percentEncode(realFileName);
        StringBuilder contentDispositionValue = new StringBuilder();
        contentDispositionValue.append("attachment; filename=")
                .append(percentEncodedFileName)
                .append(";")
                .append("filename*=")
                .append("utf-8''")
                .append(percentEncodedFileName);
        contentDispositionValue.append("attachment; filename=").append(percentEncodedFileName).append(";").append("filename*=").append("utf-8''").append(percentEncodedFileName);
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
        response.setHeader("Content-disposition", contentDispositionValue.toString());
@@ -220,8 +187,7 @@
     * @param s éœ€è¦ç™¾åˆ†å·ç¼–码的字符串
     * @return ç™¾åˆ†å·ç¼–码后的字符串
     */
    public static String percentEncode(String s) throws UnsupportedEncodingException
    {
    public static String percentEncode(String s) throws UnsupportedEncodingException {
        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
        return encode.replaceAll("\\+", "%20");
    }
@@ -232,24 +198,15 @@
     * @param photoByte å›¾åƒæ•°æ®
     * @return åŽç¼€å
     */
    public static String getFileExtendName(byte[] photoByte)
    {
    public static String getFileExtendName(byte[] photoByte) {
        String strFileExtendName = "jpg";
        if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
                && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
        {
        if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56) && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) {
            strFileExtendName = "gif";
        }
        else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
        {
        } else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) {
            strFileExtendName = "jpg";
        }
        else if ((photoByte[0] == 66) && (photoByte[1] == 77))
        {
        } else if ((photoByte[0] == 66) && (photoByte[1] == 77)) {
            strFileExtendName = "bmp";
        }
        else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
        {
        } else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) {
            strFileExtendName = "png";
        }
        return strFileExtendName;
@@ -261,10 +218,8 @@
     * @param fileName è·¯å¾„名称
     * @return æ²¡æœ‰æ–‡ä»¶è·¯å¾„的名称
     */
    public static String getName(String fileName)
    {
        if (fileName == null)
        {
    public static String getName(String fileName) {
        if (fileName == null) {
            return null;
        }
        int lastUnixPos = fileName.lastIndexOf('/');
@@ -279,10 +234,8 @@
     * @param fileName è·¯å¾„名称
     * @return æ²¡æœ‰æ–‡ä»¶è·¯å¾„和后缀的名称
     */
    public static String getNameNotSuffix(String fileName)
    {
        if (fileName == null)
        {
    public static String getNameNotSuffix(String fileName) {
        if (fileName == null) {
            return null;
        }
        String baseName = FilenameUtils.getBaseName(fileName);
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpBody.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,6 @@
package com.ruoyi.common.utils.http;
public interface HttpBody {
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpEntity.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package com.ruoyi.common.utils.http;
import java.util.HashMap;
import java.util.Map;
public class HttpEntity<T> {
    /**
     * ç©ºçš„æŠ¥æ–‡å¤´
     */
    public static final Map<String, String> EMPTY_HEADERS = new HashMap<String, String>(0);
    /**
     * æŠ¥æ–‡å¤´
     */
    private final Map<String, String> headers;
    /**
     * æŠ¥æ–‡ä½“
     */
    private final T body;
    public HttpEntity(Map<String, String> headers, T body) {
        this.headers = headers;
        this.body = body;
    }
    public HttpEntity(T body) {
        this.headers = EMPTY_HEADERS;
        this.body = body;
    }
    public Map<String, String> getHeaders() {
        return headers;
    }
    public T getBody() {
        return body;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/json/JsonRequestBody.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.ruoyi.common.utils.json;
import com.ruoyi.common.utils.http.HttpBody;
/**
 * Json格式的http请求body
*/
public interface JsonRequestBody extends HttpBody {
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/json/JsonResponseBody.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.ruoyi.common.utils.json;
import com.ruoyi.common.utils.http.HttpBody;
/**
 * Json格式的http响应body
*/
public interface JsonResponseBody extends HttpBody {
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/xml/XmlRequestBody.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
package com.ruoyi.common.utils.xml;
import com.ruoyi.common.utils.http.HttpBody;
/**
 * xml格式的http请求体
*/
public interface XmlRequestBody extends HttpBody {
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/xml/XmlResponseBody.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
package com.ruoyi.common.utils.xml;
import com.ruoyi.common.utils.http.HttpBody;
/**
 * xml格式的http响应体
*/
public interface XmlResponseBody extends HttpBody {
}
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -108,7 +108,7 @@
                // è¿‡æ»¤è¯·æ±‚
                .authorizeRequests()
                // å¯¹äºŽç™»å½•login æ³¨å†Œregister éªŒè¯ç captchaImage å…è®¸åŒ¿åè®¿é—®
                .antMatchers("/login", "/register", "/captchaImage", "/qrcode/generateStaticHtml", "/qrcode/getQRcode", "/qrcode/getFormDate", "/chat", "/system/file/admin/uploadFile", "/smartor/dingtalk/sendNotification", "/patient/read/patientInfo","/socket","/API_ESB_Service","/API_ESB_Service/Run","/magic/web/**").permitAll()
                .antMatchers("/login", "/register", "/captchaImage", "/qrcode/generateStaticHtml", "/qrcode/getQRcode", "/qrcode/getFormDate", "/chat", "/system/file/admin/uploadFile", "/smartor/dingtalk/sendNotification", "/patient/read/patientInfo","/socket","/API_ESB_Service","/API_ESB_Service/Run","/magic/web/**","/smartor/taskcall/phoneCallBack").permitAll()
                // é™æ€èµ„源,可匿名访问
                .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll().antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
                // é™¤ä¸Šé¢å¤–的所有请求全部需要鉴权认证
ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java
@@ -124,7 +124,7 @@
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
    @Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    @PostMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException {
        SysJob newJob = jobService.selectJobById(job.getJobId());
        newJob.setStatus(job.getStatus());
@@ -136,7 +136,7 @@
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
    @Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @PutMapping("/run")
    @PostMapping("/run")
    public AjaxResult run(@RequestBody SysJob job) throws SchedulerException {
        boolean result = jobService.run(job);
        return result ? success() : error("任务不存在或已过期!");
@@ -147,7 +147,7 @@
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:remove')")
    @Log(title = "定时任务", businessType = BusinessType.DELETE)
    @DeleteMapping("/{jobIds}")
    @GetMapping("/remove/{jobIds}")
    public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException {
        jobService.deleteJobByIds(jobIds);
        return success();
smartor/pom.xml
@@ -114,6 +114,12 @@
            <artifactId>json-simple</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!-- rabbitmq ä¾èµ–-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
    </dependencies>
smartor/src/main/java/com/smartor/config/PhoneUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,275 @@
package com.smartor.config;
import com.ruoyi.common.utils.HttpUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpEntity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.mail.Multipart;
import java.util.HashMap;
import java.util.Map;
@Component
public class PhoneUtils {
    @Value("${phoneIP}")
    private String phoneIP;
    /**
     * æ·»åŠ åˆ†æœºadd_user
     */
    public String addUser(String user, String pwd) {
        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("password", pwd);
        return sendReq(map, "/tel/ai_api/add_user");
    }
    /**
     * åˆ é™¤åˆ†æœºdelete_user
     *
     * @return
     */
    public String delUser(String user) {
        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        return sendReq(map, "/tel/ai_api/delete_user");
    }
    /**
     * 3、检查分机是否存在check_user
     *
     * @return
     */
    public String checkUser(String user) {
        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        return sendReq(map, "/tel/ai_api/check_user");
    }
    /**
     * åˆ—出全部坐席或者指定坐席 list_agent
     *
     * @param name
     * @return
     */
    public String listAgent(String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        return sendReq(map, "/tel/ai_api/list_agent");
    }
    /**
     * æ·»åŠ åå¸­add_agent
     * å‘系统中添加一个坐席,后续需要set_agent_state,set_agent_status,set_agent_contact, tier_add è®¾ç½®åå¸­çж体,sip_uri和把坐席加入/绑定一个呼叫队列
     *
     * @param name
     * @return
     */
    public String addAgent(String name, String type) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        if (StringUtils.isEmpty(type)) map.put("type", "callback");
        return sendReq(map, "/tel/ai_api/add_agent");
    }
    /**
     * åˆ é™¤åå¸­del_agent
     * ä»Žå‘¼å«é˜Ÿåˆ—删除坐席
     *
     * @param name
     * @return
     */
    public String delAgent(String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        return sendReq(map, "/tel/ai_api/del_agent");
    }
    /**
     * èŽ·å–åå¸­å½“å‰æ‰€åœ¨é€šè¯çš„uuid
     *
     * @param name
     * @return
     */
    public String getAgentUUID(String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        return sendReq(map, "/tel/ai_api/get_agent_uuid");
    }
    /**
     * æ·»åŠ åå¸­åŽ(add_agent),需要设置坐席地址(sip uri),坐席才可以被访问到
     *
     * @param name
     * @param contact
     * @return
     */
    public String setAgentUUID(String name, String contact) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        map.put("contact", contact);
        return sendReq(map, "/tel/ai_api/set_agent_contact");
    }
    /**
     * è®¾ç½®åå¸­çš„status,有固定几个状态
     *
     * @param name
     * @param status
     * @return
     */
    public String setAgentStatus(String name, String status) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        map.put("status", status);
        return sendReq(map, "/tel/ai_api/set_agent_status");
    }
    /**
     * èŽ·å–åå¸­çŠ¶æ€
     *
     * @param name
     * @return
     */
    public String getAgentStatus(String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        return sendReq(map, "/tel/ai_api/get_agent_status");
    }
    /**
     * è®¾è®¾ç½®åå¸­
     *
     * @param name
     * @param state
     * @return
     */
    public String setAgentState(String name, String state) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        map.put("state", state);
        return sendReq(map, "/tel/ai_api/set_agent_state");
    }
    /**
     * èŽ·å–åå¸­çŠ¶æ€
     *
     * @param name
     * @return
     */
    public String getAgentState(String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        return sendReq(map, "/tel/ai_api/set_agent_state");
    }
    /**
     * æ‰‹åЍ外呼
     *
     * @return
     */
    public String manualOutbound(String kg_uuid, String kg_file, String data, String app_id, String ani, String special_ch, String sign, String extension, String dnis, Boolean force_call) {
        Map<String, Object> map = new HashMap<>();
        map.put("kg_uuid", kg_uuid);
        map.put("kg_file", kg_file);
        map.put("data", data);
        map.put("app_id", app_id);
        map.put("ani", ani);
        map.put("special_ch", special_ch);
        map.put("sign", sign);
        map.put("extension", extension);
        map.put("dnis", dnis);
        map.put("force_call", force_call);
        if (force_call == null) map.put("force_call", true);
        return sendReq(map, "/tel/ai_api/set_agent_state");
    }
    /**
     * tts合成和播放
     *
     * @param fileText
     * @param uuid
     * @return
     */
    public String ttsPlayback(String fileText, String uuid) {
        Map<String, Object> map = new HashMap<>();
        map.put("text", fileText);
        map.put("uuid", uuid);
        return sendReq(map, "/tel/ai_api/set_agent_state");
    }
    /**
     * wav文件播放接口
     *
     * @param wav_file
     * @param uuid
     * @return
     */
    public String manualOutbound(Multipart wav_file, String uuid) {
        Map<String, Object> map = new HashMap<>();
        map.put("wav_file", wav_file);
        map.put("uuid", uuid);
        return sendReq(map, "/tel/ai_api/set_agent_state");
    }
    /**
     * æœºå™¨äººå¤–呼 ob
     *
     * @return
     */
    public String ob(String kg_uuid, String kg_file, String data, String app_id, String ani, String special_ch, String sign, String extension, String dnis, Boolean call_uuid, Boolean force_call) {
        Map<String, Object> map = new HashMap<>();
        map.put("kg_uuid", kg_uuid);
        map.put("kg_file", kg_file);
        map.put("data", data);
        map.put("app_id", app_id);
        map.put("ani", ani);
        map.put("special_ch", special_ch);
        map.put("sign", sign);
        map.put("extension", extension);
        map.put("dnis", dnis);
        map.put("call_uuid", call_uuid);
        map.put("force_call", force_call);
        if (force_call == null) map.put("force_call", true);
        return sendReq(map, "/tel/ai_api/set_agent_state");
    }
    /**
     * æŒ‚断通话
     *
     * @return
     */
    public String hangup(String kg_uuid, String dnis, String data, String app_id, String ani, String special_ch, String sign, Boolean call_uuid) {
        Map<String, Object> map = new HashMap<>();
        map.put("kg_uuid", kg_uuid);
        map.put("data", data);
        map.put("app_id", app_id);
        map.put("ani", ani);
        map.put("special_ch", special_ch);
        map.put("sign", sign);
        map.put("dnis", dnis);
        map.put("call_uuid", call_uuid);
        return sendReq(map, "/tel/ai_api/set_agent_state");
    }
    private String sendReq(Map<String, Object> map, String path) {
        HttpEntity<Map<String, Object>> req = new HttpEntity<>(getHead(), map);
        HttpEntity<String> stringHttpEntity = HttpUtil.postJsonRequestV2(phoneIP + path, req, String.class);
        return stringHttpEntity.getBody();
    }
    private Map<String, String> getHead() {
        HashMap<String, String> header = new HashMap<>();
        header.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko");
        header.put("Content-Type", "application/json");
        return header;
    }
}
smartor/src/main/java/com/smartor/config/RabbitMqConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,91 @@
package com.smartor.config;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class RabbitMqConfig {
//    public static final String EXCHANGE_NAME = "phone_topic_exchange2";
//    public static final String QUEUE_NAME = "phone_queue";
    //
//    /**
//     * topic交换机,并持久化
//     */
//    @Bean(EXCHANGE_NAME)
//    public Exchange phoneExchange() {
//        Map<String, Object> arguments = new HashMap<>();
//        //指定通信方式为topic
//        arguments.put("x-delayed-type", "topic");
//        //使用CustomExchange类创建,类型要指定为“x-delayed-message”类型
//        Exchange exchange = new CustomExchange(EXCHANGE_NAME, "x-delayed-message", true, false, arguments);
//        return exchange;
//
////
////        return ExchangeBuilder.topicExchange(EXCHANGE_NAME).durable(true).build();
//    }
//
//
//    /**
//     * é˜Ÿåˆ—
//     */
//    @Bean(QUEUE_NAME)
//    public Queue phoneQueue() {
//        return QueueBuilder.durable(QUEUE_NAME).build();
//    }
//
//    /**
//     * äº¤æ¢æœºä¸Žé˜Ÿåˆ—的绑定
//     */
//    @Bean
//    public Binding bindQueueExchange(@Qualifier(QUEUE_NAME) Queue phoneQueue, @Qualifier(EXCHANGE_NAME) Exchange phoneExchange) {
//        return BindingBuilder.bind(phoneQueue).to(phoneExchange).with(" phone.#").noargs();
//    }
//定义延迟队列
    public static final String phone_queue = "phone_queue";
    //定义延迟交换机
    public static final String phone_exchange = "phone_exchange";
    //定义路由键
    public static final String routing_key = "phone.123";
    /**
     * å®šä¹‰å»¶è¿Ÿé˜Ÿåˆ—
     *
     * @return
     */
    @Bean
    public Queue delayQueue() {
        return new Queue(phone_queue, true);
    }
    /**
     * å»¶æ—¶é˜Ÿåˆ—交换机
     * äº¤æ¢æœºç±»åž‹ï¼šCustomExchange
     *
     * @return
     */
    @Bean
    public CustomExchange delayExchange() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "topic");
        return new CustomExchange(phone_exchange, "x-delayed-message", true, false, args);
    }
    /**
     * ä¸ºå»¶è¿Ÿé˜Ÿåˆ—绑定交换机
     *
     * @param queue
     * @param exchange
     * @return
     */
    @Bean
    public Binding delayBinding(Queue queue, CustomExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(routing_key).noargs();
    }
}
smartor/src/main/java/com/smartor/domain/IvrLibaExtemplate.java
@@ -27,7 +27,7 @@
     * ä¸»é”®id
     */
    @ApiModelProperty("主键id")
    private String ID;
    private Long ID;
    /**
     * æ¨¡ç‰ˆåå­—
smartor/src/main/java/com/smartor/domain/IvrLibaExtemplatescript.java
@@ -1,6 +1,8 @@
package com.smartor.domain;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
@@ -26,14 +28,14 @@
     * ä¸»é”®id
     */
    @ApiModelProperty("主键id")
    private String ID;
    private Long ID;
    /**
     * æ¨¡ç‰ˆåº“id
     */
    @Excel(name = "模版库id")
    @ApiModelProperty("模版库id")
    private String extID;
    private Long extID;
    /**
     * åºå·id
@@ -57,12 +59,34 @@
    private String switchWav;
    /**
     * åŒ¹é…è§„则
     * åŒ¹é…è§„则(包含关系)
     */
    @Excel(name = "匹配规则")
    @ApiModelProperty("匹配规则")
    @Excel(name = "匹配规则(包含关系)")
    @ApiModelProperty("匹配规则(包含关系)")
    private String selfRegex;
    /**
     * åŒ¹é…è§„则(不包含关系)
     */
    @Excel(name = "匹配规则(不包含关系)")
    @ApiModelProperty("匹配规则(不包含关系)")
    private String selfRegex2;
    @Excel(name = "正则关键字集合(含)")
    private String nodynamiccruxsJson;
    @Excel(name = "正则关键字集合(不含)")
    private String dynamiccruxsJson;
    @ApiModelProperty(value = "正则关键字(含)")
    @Excel(name = "正则关键字(含)")
    private List<String> nodynamiccruxs = new ArrayList<>();
    @ApiModelProperty(value = "正则关键字(不含)")
    @Excel(name = "正则关键字(不含)")
    private List<String> dynamiccruxs = new ArrayList<>();
    /**
     * å¯ç”¨
     */
@@ -106,6 +130,13 @@
    private Long pid;
    /**
     * æ˜¯å¦ç»“束 0:不结束   1:结束
     */
    @Excel(name = "是否结束 0:不结束   1:结束")
    @ApiModelProperty("是否结束 0:不结束   1:结束")
    private Long isEnd;
    /**
     * GUID
     */
    @Excel(name = "GUID")
smartor/src/main/java/com/smartor/domain/IvrLibaScriptTargetoption.java
@@ -277,11 +277,7 @@
    }
    public void setNodynamiccruxsJson(String nodynamiccruxsJson) {
        if (this.nodynamiccruxs != null) {
            this.nodynamiccruxsJson = new Gson().toJson(this.nodynamiccruxs);
        } else {
            this.nodynamiccruxsJson = nodynamiccruxsJson;
        }
    }
    public String getDynamiccruxsJson() {
@@ -289,11 +285,7 @@
    }
    public void setDynamiccruxsJson(String dynamiccruxsJson) {
        if (this.dynamiccruxs != null) {
            this.dynamiccruxsJson = new Gson().toJson(this.dynamiccruxs);
        } else {
            this.dynamiccruxsJson = dynamiccruxsJson;
        }
    }
    public List<String> getNodynamiccruxs() {
smartor/src/main/java/com/smartor/domain/IvrLibaTargetoption.java
@@ -235,11 +235,7 @@
    }
    public void setNodynamiccruxsJson(String nodynamiccruxsJson) {
        if (this.nodynamiccruxs != null) {
            this.nodynamiccruxsJson = new Gson().toJson(this.nodynamiccruxs);
        } else {
            this.nodynamiccruxsJson = nodynamiccruxsJson;
        }
    }
    public String getDynamiccruxsJson() {
@@ -247,11 +243,7 @@
    }
    public void setDynamiccruxsJson(String dynamiccruxsJson) {
        if (this.dynamiccruxs != null) {
            this.dynamiccruxsJson = new Gson().toJson(this.dynamiccruxs);
        } else {
            this.dynamiccruxsJson = dynamiccruxsJson;
        }
    }
    public List<String> getNodynamiccruxs() {
smartor/src/main/java/com/smartor/domain/IvrLibaTemplate.java
@@ -1,6 +1,8 @@
package com.smartor.domain;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
@@ -152,8 +154,8 @@
    /**
     * é€šç”¨åŒ¹é…è¯æœ¯id
     */
    @Excel(name = "通用匹配话术id")
    @ApiModelProperty(value = "通用匹配话术id")
    @Excel(name = "通用匹配话术id(通用模板ID)")
    @ApiModelProperty(value = "通用匹配话术id(通用模板ID)")
    private String submoduleID;
    /**
@@ -248,6 +250,13 @@
    private Long mateNum;
    /**
     * é™é»˜æ¬¡æ•°
     */
    @Excel(name = "静默次数")
    @ApiModelProperty(value = "静默次数")
    private Long noVoiceNum = 0L;
    /**
     * GUID
     */
    @Excel(name = "GUID")
@@ -313,17 +322,18 @@
    private String otherdata;
    /**
     * éšè®¿å‰
     * éšè®¿å‰è¯æœ¯ï¼ˆå¼€åœºç™½ï¼‰
     */
    @Excel(name = "随访前")
    @ApiModelProperty(value = "随访前")
    @Excel(name = "随访前话术(开场白)")
    @ApiModelProperty(value = "随访前话术(开场白)")
    private String revisitBefore;
    /**
     * éšè®¿åŽ
     */
    @Excel(name = "随访后")
    @ApiModelProperty(value = "随访后")
    @Excel(name = "随访后话术(结束语)")
    @ApiModelProperty(value = "随访后话术(结束语)")
    private String revisitAfter;
}
smartor/src/main/java/com/smartor/domain/IvrLibaTemplateScript.java
@@ -222,10 +222,16 @@
    private Integer targettype;
    /**
     * ä¸‹ä¸€é¢˜
     */
    @ApiModelProperty(value = "下一题")
    private Integer nextQuestion;
    /**
     * æ˜¯å¦å­˜åœ¨æ“ä½œï¼š1 æ–°å¢ž 2修改 3删除
     */
    @ApiModelProperty(value = "指标ID")
    private Long targetid;
    private Integer targetid;
    /**
@@ -233,4 +239,11 @@
     */
    @ApiModelProperty(value = "指标值")
    private Integer targetvalue;
    /**
     * æ ‡ç­¾
     */
    @Excel(name = "其它数据(存储变量)")
    @ApiModelProperty(value = "其它数据(存储变量)")
    private String otherdata;
}
smartor/src/main/java/com/smartor/domain/IvrLibaTemplateScriptVO.java
@@ -217,7 +217,7 @@
    /**
     * åŸºç¡€æŒ‡æ ‡id
     */
    @ApiModelProperty(value = "基础指标id")
    @ApiModelProperty(value = "基础指标id(暂时当本题序号)")
    private Integer targetid;
@@ -235,6 +235,19 @@
    private String questiontitle;
    /**
     * ä¸‹ä¸€é¢˜
     */
    @ApiModelProperty(value = "下一题")
    private Integer nextQuestion;
    /**
     * æ ‡ç­¾
     */
    @Excel(name = "其它数据(存储变量)")
    @ApiModelProperty(value = "其它数据(存储变量)")
    private String otherdata;
    /**
     * è¯æœ¯é€‰é¡¹
     */
    @ApiModelProperty(value = "话术选项")
smartor/src/main/java/com/smartor/domain/IvrLibaTemplateTargetoption.java
@@ -1,18 +1,15 @@
package com.smartor.domain;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.google.gson.Gson;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * æ¨¡æ¿æŒ‡æ ‡é€‰é¡¹åº“对象 ivr_liba_template_targetoption
@@ -20,6 +17,7 @@
 * @author ruoyi
 * @date 2023-12-23
 */
@Data
@ApiModel(value = "IvrLibaTemplateTargetoption", description = "模板指标选项库对象")
public class IvrLibaTemplateTargetoption extends BaseEntity {
    private static final long serialVersionUID = 1L;
@@ -204,235 +202,17 @@
    @ApiModelProperty(value = "是否存在操作:1 æ–°å¢ž 2修改 3删除")
    private Integer isoperation;
    public Long getId() {
        return id;
    }
    /**
     * æ˜¯å¦æ˜¯ç”¨æˆ·é€‰æ‹©çš„选项
     */
    @ApiModelProperty(value = "是否是用户选择的选项")
    private Boolean isUserOperation = false;
    public void setId(Long id) {
        this.id = id;
    }
    public Long getTargetid() {
        return targetid;
    }
    /**
     * ä¸‹ä¸€é¢˜
     */
    @ApiModelProperty(value = "下一题")
    private Integer nextQuestion;
    public void setTargetid(Long targetid) {
        this.targetid = targetid;
    }
    public String getTargetname() {
        return targetname;
    }
    public void setTargetname(String targetname) {
        this.targetname = targetname;
    }
    public Long getTemplateID() {
        return templateID;
    }
    public void setTemplateID(Long templateID) {
        this.templateID = templateID;
    }
    public Long getScriptid() {
        return scriptid;
    }
    public void setScriptid(Long scriptid) {
        this.scriptid = scriptid;
    }
    public String getTargettype() {
        return targettype;
    }
    public void setTargettype(String targettype) {
        this.targettype = targettype;
    }
    public String getCategoryName() {
        return categoryName;
    }
    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }
    public String getTargetvalue() {
        return targetvalue;
    }
    public void setTargetvalue(String targetvalue) {
        this.targetvalue = targetvalue;
    }
    public String getTargetregex() {
        return targetregex;
    }
    public void setTargetregex(String targetregex) {
        this.targetregex = targetregex;
    }
    public String getTargetregex2() {
        return targetregex2;
    }
    public void setTargetregex2(String targetregex2) {
        this.targetregex2 = targetregex2;
    }
    public String getNodynamiccruxsJson() {
        return nodynamiccruxsJson;
    }
    public void setNodynamiccruxsJson(String nodynamiccruxsJson) {
        if (this.nodynamiccruxs != null) {
            this.nodynamiccruxsJson = new Gson().toJson(this.nodynamiccruxs);
        } else {
            this.nodynamiccruxsJson = nodynamiccruxsJson;
        }
    }
    public String getDynamiccruxsJson() {
        return dynamiccruxsJson;
    }
    public void setDynamiccruxsJson(String dynamiccruxsJson) {
        if (this.dynamiccruxs != null) {
            this.dynamiccruxsJson = new Gson().toJson(this.dynamiccruxs);
        } else {
            this.dynamiccruxsJson = dynamiccruxsJson;
        }
    }
    public List<String> getNodynamiccruxs() {
        return nodynamiccruxs;
    }
    public void setNodynamiccruxs(List<String> nodynamiccruxs) {
        this.nodynamiccruxs = nodynamiccruxs;
    }
    public List<String> getDynamiccruxs() {
        return dynamiccruxs;
    }
    public void setDynamiccruxs(List<String> dynamiccruxs) {
        this.dynamiccruxs = dynamiccruxs;
    }
    public String getOptiondesc() {
        return optiondesc;
    }
    public void setOptiondesc(String optiondesc) {
        this.optiondesc = optiondesc;
    }
    public String getLanguage() {
        return language;
    }
    public void setLanguage(String language) {
        this.language = language;
    }
    public String getVersion() {
        return version;
    }
    public void setVersion(String version) {
        this.version = version;
    }
    public String getGroupid() {
        return groupid;
    }
    public void setGroupid(String groupid) {
        this.groupid = groupid;
    }
    public Long getIsabnormal() {
        return isabnormal;
    }
    public void setIsabnormal(Long isabnormal) {
        this.isabnormal = isabnormal;
    }
    public Long getWarnup() {
        return warnup;
    }
    public void setWarnup(Long warnup) {
        this.warnup = warnup;
    }
    public Long getWarndown() {
        return warndown;
    }
    public void setWarndown(Long warndown) {
        this.warndown = warndown;
    }
    public String getDelFlag() {
        return delFlag;
    }
    public void setDelFlag(String delFlag) {
        this.delFlag = delFlag;
    }
    public Long getIsupload() {
        return isupload;
    }
    public void setIsupload(Long isupload) {
        this.isupload = isupload;
    }
    public Date getUploadTime() {
        return uploadTime;
    }
    public void setUploadTime(Date uploadTime) {
        this.uploadTime = uploadTime;
    }
    public String getOrgid() {
        return orgid;
    }
    public void setOrgid(String orgid) {
        this.orgid = orgid;
    }
    public Long getPid() {
        return pid;
    }
    public void setPid(Long pid) {
        this.pid = pid;
    }
    public String getGuid() {
        return guid;
    }
    public void setGuid(String guid) {
        this.guid = guid;
    }
    public Integer getIsoperation() {
        return isoperation;
    }
    public void setIsoperation(Integer isoperation) {
        this.isoperation = isoperation;
    }
}
smartor/src/main/java/com/smartor/domain/IvrLibaTemplateVO.java
@@ -1,5 +1,6 @@
package com.smartor.domain;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
@@ -152,8 +153,8 @@
    /**
     * é€šç”¨åŒ¹é…è¯æœ¯id
     */
    @Excel(name = "通用匹配话术id")
    @ApiModelProperty(value = "通用匹配话术id")
    @Excel(name = "通用匹配话术id(通用模板ID)")
    @ApiModelProperty(value = "通用匹配话术id(通用模板ID)")
    private String submoduleID;
    /**
@@ -245,7 +246,7 @@
     */
    @Excel(name = "无匹配次数")
    @ApiModelProperty(value = "无匹配次数")
    private Long mateNum;
    private Long mateNum = 0L;
    /**
     * GUID
@@ -318,6 +319,20 @@
    private String suitway;
    /**
     * é™é»˜æ¬¡æ•°
     */
    @Excel(name = "静默次数")
    @ApiModelProperty(value = "静默次数")
    private Long noVoiceNum = 0L;
    /**
     * æ ‡ç­¾
     */
    @Excel(name = "其它数据(存储变量)")
    @ApiModelProperty(value = "其它数据(存储变量)")
    private String otherdata;
    /**
     * æ˜¯å¦å­˜åœ¨æ“ä½œï¼š1 æ–°å¢ž 2修改 3删除
     */
    @ApiModelProperty(value = "是否存在操作:1 æ–°å¢ž 2修改 3删除")
smartor/src/main/java/com/smartor/domain/IvrTaskcall.java
@@ -1,6 +1,7 @@
package com.smartor.domain;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
@@ -26,6 +27,12 @@
     */
    @ApiModelProperty(value = "主键")
    private Long id;
    /**
     *
     */
    @ApiModelProperty(value = "任务ID")
    private Long taskid;
    /**
     * å‘送人
@@ -305,10 +312,10 @@
    private String textParam;
    /**
     * å®£æ•™å½¢å¼ :文本、图片、语音、视频、混合
     * å®£æ•™å½¢å¼ : 1,短信、2,线下、3,语音、4,视频、5,纸质  6.链接  7.钉钉   8.微信
     */
    @Excel(name = " å®£æ•™å½¢å¼ :文本、图片、语音、视频、混合")
    @ApiModelProperty("宣教形式 : 1,文本、2,图片、3,语音、4,视频、5,混合")
    @Excel(name = " å®£æ•™å½¢å¼ : 1,短信、2,线下、3,语音、4,视频、5,纸质  6.二维码  7.钉钉   8.微信")
    @ApiModelProperty("宣教形式 :  1,短信、2,线下、3,语音、4,视频、5,纸质  6.链接  7.钉钉  8.微信")
    private String serviceform;
    /**
@@ -353,4 +360,20 @@
    @ApiModelProperty(value = "pageSize")
    private Integer pageSize;
    /**
     * å‘送类型: 1 æ—¶é—´æ®µ   2 æ—¶é—´ç‚¹   3 å³åˆ»å‘送
     */
    @ApiModelProperty(value = "发送类型: 1 æ—¶é—´æ®µ   2 æ—¶é—´ç‚¹   3 å³åˆ»å‘送")
    private String sendType;
    /**
     * å‘送时间段
     */
    @Excel(name = "发送时间段")
    @ApiModelProperty(value = "发送时间段")
    private String sendTimeSlot;
}
smartor/src/main/java/com/smartor/domain/IvrTaskcallMQ.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
package com.smartor.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * MQ任务
 *
 * @author ruoyi
 * @date 2024-02-02
 */
@Data
public class IvrTaskcallMQ extends BaseEntity {
    private static final long serialVersionUID = 1L;
    /**
     * ä»»åŠ¡ID
     */
    @Excel(name = " ä»»åŠ¡ID ")
    @ApiModelProperty(value = "任务ID")
    private Long taskid;
    /**
     * æ¨¡æ¿ID
     */
    @Excel(name = "  æ¨¡æ¿ID")
    @ApiModelProperty(value = "模板ID")
    private String templateid;
    /**
     * æ¨¡æ¿ç±»åž‹
     */
    @Excel(name = "  æ¨¡æ¿ç±»åž‹")
    @ApiModelProperty(value = "模板类型")
    private String templateType;
    /**
     * å‘送类型: 1 æ—¶é—´æ®µ   2 æ—¶é—´ç‚¹   3 å³åˆ»å‘送
     */
    @ApiModelProperty(value = "发送类型: 1 æ—¶é—´æ®µ   2 å³åˆ»å‘送")
    private String sendType;
    /**
     * å‘送时间段
     */
    @ApiModelProperty(value = "发送时间段 ")
    private List<TaskSendTimeVO> sendTimeslot;
}
smartor/src/main/java/com/smartor/domain/IvrTaskcallVO.java
@@ -106,6 +106,12 @@
    private String templatename;
    /**
     * å‘送类型: 1 æ—¶é—´æ®µ   2 æ—¶é—´ç‚¹   3 å³åˆ»å‘送
     */
    @ApiModelProperty(value = "发送类型: 1 æ—¶é—´æ®µ   2 å³åˆ»å‘送")
    private String sendType;
    /**
     * å‘送日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
@@ -159,7 +165,7 @@
     * å‘送状态
     */
    @Excel(name = " å‘送状态 ")
    @ApiModelProperty(value = "发送状态")
    @ApiModelProperty(value = "发送状态 ï¼š1 å¼€å§‹  2 ä¸­æ­¢  3 ç»“束")
    private Long sendstate;
    /**
@@ -361,6 +367,13 @@
    private String preachcontent;
    /**
     * å‘送时间段
     */
    @ApiModelProperty(value = "发送时间段 ")
    private List<TaskSendTimeVO> sendTimeslot;
    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).append("id", getId()).append("sendname", getSendname()).append("phone", getPhone()).append("sex", getSex()).append("age", getAge()).append("sfzh", getSfzh()).append("addr", getAddr()).append("senderdetail", getSenderdetail()).append("type", getType()).append("taskid", getTaskid()).append("templateid", getTemplateid()).append("templatename", getTemplatename()).append("senddate", getSenddate()).append("sendlimitabegin", getSendlimitabegin()).append("sendlimitaend", getSendlimitaend()).append("sendlimitpbegin", getSendlimitpbegin()).append("sendlimitpend", getSendlimitpend()).append("sendlimitnbegin", getSendlimitnbegin()).append("sendlimitnend", getSendlimitnend()).append("sendstate", getSendstate()).append("senduuid", getSenduuid()).append("result", getResult()).append("finishtime", getFinishtime()).append("userid", getUserid()).append("username", getUsername()).append("outbounduuid", getOutbounduuid()).append("recordid", getRecordid()).append("recallcount", getRecallcount()).append("exrecallcount", getExrecallcount()).append("pulltime", getPulltime()).append("bqsms", getBqsms()).append("bhsms", getBhsms()).append("deptcode", getDeptcode()).append("labelstatus", getLabelstatus()).append("delFlag", getDelFlag()).append("updateBy", getUpdateBy()).append("updateTime", getUpdateTime()).append("createBy", getCreateBy()).append("createTime", getCreateTime()).append("isupload", getIsupload()).append("uploadTime", getUploadTime()).append("orgid", getOrgid()).append("pid", getPid()).append("guid", getGuid()).append("textParam", getTextParam()).toString();
smartor/src/main/java/com/smartor/domain/QuestionMessage.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.smartor.domain;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class QuestionMessage {
    //    //题号targetId
//    private Integer code;
    //返回的内容
    private String content;
    //开场白
    private String kcb = null;
    //结束语
    private String jsy = null;
    //当前问题
    private IvrLibaTemplateScriptVO nowQuestion = new IvrLibaTemplateScriptVO();
    //问题清单
    private List<IvrLibaTemplateScriptVO> questionList = new ArrayList();
}
smartor/src/main/java/com/smartor/domain/SocketMessage.java
@@ -8,6 +8,11 @@
    private String type;
    //内容(发送的文本内容)
    private String content;
    //模板ID
    private Long templateId;
    //问题信息
    private QuestionMessage questionMessage;
    //用户ID(接收放)
    private String userId;
    //图片
smartor/src/main/java/com/smartor/domain/TaskSendTimeVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package com.smartor.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * å•一任务发送时间
 *
 * @author ruoyi
 * @date 2024-02-02
 */
@Data
public class TaskSendTimeVO {
    private static final long serialVersionUID = 1L;
    /**
     * å¼€å§‹æ—¶é—´
     */
    @ApiModelProperty(value = "开始时间")
    private String begantime;
    /**
     * å®£æ•™å†…容
     */
    @ApiModelProperty(value = "结束时间")
    private String endtime;
    /**
     * åºå·
     */
    @ApiModelProperty(value = "序号")
    private Integer xh;
}
smartor/src/main/java/com/smartor/mapper/IvrLibaExtemplateMapper.java
@@ -36,7 +36,7 @@
     * @param ivrLibaExtemplate é€šè¿‡æ¨¡æ¿
     * @return ç»“æžœ
     */
    public int insertIvrLibaExtemplate(IvrLibaExtemplate ivrLibaExtemplate);
    public Boolean insertIvrLibaExtemplate(IvrLibaExtemplate ivrLibaExtemplate);
    /**
     * ä¿®æ”¹é€šè¿‡æ¨¡æ¿
@@ -52,7 +52,7 @@
     * @param ID é€šè¿‡æ¨¡æ¿ä¸»é”®
     * @return ç»“æžœ
     */
    public int deleteIvrLibaExtemplateByID(String ID);
    public int deleteIvrLibaExtemplateByID(Long ID);
    /**
     * æ‰¹é‡åˆ é™¤é€šè¿‡æ¨¡æ¿
@@ -60,5 +60,5 @@
     * @param IDs éœ€è¦åˆ é™¤çš„æ•°æ®ä¸»é”®é›†åˆ
     * @return ç»“æžœ
     */
    public int deleteIvrLibaExtemplateByIDs(String[] IDs);
    public int deleteIvrLibaExtemplateByIDs(Long[] IDs);
}
smartor/src/main/java/com/smartor/mapper/IvrLibaExtemplatescriptMapper.java
@@ -2,6 +2,7 @@
import com.smartor.domain.IvrLibaExtemplatescript;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -12,8 +13,7 @@
 * @date 2023-12-27
 */
@Mapper
public interface IvrLibaExtemplatescriptMapper
{
public interface IvrLibaExtemplatescriptMapper {
    /**
     * æŸ¥è¯¢é€šç”¨æ¨¡æ¿è¯æœ¯
     * 
@@ -29,6 +29,14 @@
     * @return é€šç”¨æ¨¡æ¿è¯æœ¯é›†åˆ
     */
    public List<IvrLibaExtemplatescript> selectIvrLibaExtemplatescriptList(IvrLibaExtemplatescript ivrLibaExtemplatescript);
    /**
     * æŸ¥è¯¢é€šç”¨æ¨¡æ¿è¯æœ¯åˆ—表
     *
     * @param IDs é€šç”¨æ¨¡æ¿è¯æœ¯é€šè¿‡ids
     * @return é€šç”¨æ¨¡æ¿è¯æœ¯é›†åˆ
     */
    public List<IvrLibaExtemplatescript> queryIvrLibaExtemplatescriptList(@Param("IDs")List<Long> IDs);
    /**
     * æ–°å¢žé€šç”¨æ¨¡æ¿è¯æœ¯
@@ -52,7 +60,7 @@
     * @param ID é€šç”¨æ¨¡æ¿è¯æœ¯ä¸»é”®
     * @return ç»“æžœ
     */
    public int deleteIvrLibaExtemplatescriptByID(String ID);
    public int deleteIvrLibaExtemplatescriptByID(Long ID);
    /**
     * æ‰¹é‡åˆ é™¤é€šç”¨æ¨¡æ¿è¯æœ¯
@@ -60,5 +68,5 @@
     * @param IDs éœ€è¦åˆ é™¤çš„æ•°æ®ä¸»é”®é›†åˆ
     * @return ç»“æžœ
     */
    public int deleteIvrLibaExtemplatescriptByIDs(String[] IDs);
    public int deleteIvrLibaExtemplatescriptByIDs(Long[] IDs);
}
smartor/src/main/java/com/smartor/mapper/IvrTaskcallMapper.java
@@ -1,7 +1,9 @@
package com.smartor.mapper;
import com.smartor.domain.IvrTaskcall;
import com.smartor.domain.IvrTaskcallVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -29,6 +31,8 @@
     */
    public List<IvrTaskcall> selectIvrTaskcallList(IvrTaskcall ivrTaskcall);
    public IvrTaskcallVO queryTaskByCondition(IvrTaskcallVO ivrTaskcallVO);
    /**
     * æ–°å¢žå•一任务(随访)
     *
@@ -40,7 +44,6 @@
    /**
     * ä¿®æ”¹å•一任务(随访)
     *
     * @param ivrTaskcall å•一任务(随访)
     * @return ç»“æžœ
     */
    public int updateIvrTaskcall(IvrTaskcall ivrTaskcall);
@@ -53,4 +56,11 @@
     */
    public int deleteIvrTaskcallById(Long id);
    /**
     * åˆ é™¤å•一任务(随访)
     *
     * @return ç»“æžœ
     */
    public List<IvrTaskcall> getDataByTime(@Param("beganTime") String beganTime, @Param("endTime") String endTime);
}
smartor/src/main/java/com/smartor/service/IIvrLibaExtemplateService.java
@@ -34,7 +34,7 @@
     * @param ivrLibaExtemplate é€šè¿‡æ¨¡æ¿
     * @return ç»“æžœ
     */
    public int insertIvrLibaExtemplate(IvrLibaExtemplate ivrLibaExtemplate);
    public IvrLibaExtemplate insertIvrLibaExtemplate(IvrLibaExtemplate ivrLibaExtemplate);
    /**
     * ä¿®æ”¹é€šè¿‡æ¨¡æ¿
@@ -50,7 +50,7 @@
     * @param IDs éœ€è¦åˆ é™¤çš„通过模板主键集合
     * @return ç»“æžœ
     */
    public int deleteIvrLibaExtemplateByIDs(String[] IDs);
    public int deleteIvrLibaExtemplateByIDs(Long[] IDs);
    /**
     * åˆ é™¤é€šè¿‡æ¨¡æ¿ä¿¡æ¯
@@ -58,5 +58,5 @@
     * @param ID é€šè¿‡æ¨¡æ¿ä¸»é”®
     * @return ç»“æžœ
     */
    public int deleteIvrLibaExtemplateByID(String ID);
    public int deleteIvrLibaExtemplateByID(Long ID);
}
smartor/src/main/java/com/smartor/service/IIvrLibaExtemplatescriptService.java
@@ -50,7 +50,7 @@
     * @param IDs éœ€è¦åˆ é™¤çš„通用模板话术主键集合
     * @return ç»“æžœ
     */
    public int deleteIvrLibaExtemplatescriptByIDs(String[] IDs);
    public int deleteIvrLibaExtemplatescriptByIDs(Long[] IDs);
    /**
     * åˆ é™¤é€šç”¨æ¨¡æ¿è¯æœ¯ä¿¡æ¯
@@ -58,5 +58,5 @@
     * @param ID é€šç”¨æ¨¡æ¿è¯æœ¯ä¸»é”®
     * @return ç»“æžœ
     */
    public int deleteIvrLibaExtemplatescriptByID(String ID);
    public int deleteIvrLibaExtemplatescriptByID(Long ID);
}
smartor/src/main/java/com/smartor/service/IIvrTaskcallService.java
@@ -3,6 +3,7 @@
import com.smartor.domain.HeTaskVO;
import com.smartor.domain.IvrTaskcall;
import com.smartor.domain.IvrTaskcallVO;
import com.smartor.domain.PhoneCallBackVO;
import java.util.List;
@@ -61,4 +62,20 @@
     */
    public int insertOrUpdateTask(IvrTaskcallVO ivrTaskcallVO);
    /**
     * ä»»åŠ¡å‘é€æ‰§è¡Œ
     *
     * @param ivrTaskcallVO
     * @return ç»“æžœ
     */
    public int heTaskSend(IvrTaskcallVO ivrTaskcallVO);
    /**
     * ä»»åŠ¡å‘é€æ‰§è¡Œ
     *
     * @param phoneCallBackVO
     * @return ç»“æžœ
     */
    public PhoneCallBackVO phoneCallBack(PhoneCallBackVO phoneCallBackVO);
}
smartor/src/main/java/com/smartor/service/PersonVoiceService.java
@@ -18,7 +18,7 @@
    /**
     * ä¸€å¥è¯è¯†åˆ«
     */
    public String texttospeech(String textspeech);
    public String texttospeech(String textspeech, String filePath);
    public Boolean explainHTML();
}
smartor/src/main/java/com/smartor/service/impl/IvrLibaExtemplateServiceImpl.java
@@ -8,6 +8,7 @@
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.UUID;
/**
 * é€šè¿‡æ¨¡æ¿Service业务层处理
@@ -49,9 +50,13 @@
     * @return ç»“æžœ
     */
    @Override
    public int insertIvrLibaExtemplate(IvrLibaExtemplate ivrLibaExtemplate) {
    public IvrLibaExtemplate insertIvrLibaExtemplate(IvrLibaExtemplate ivrLibaExtemplate) {
        ivrLibaExtemplate.setCreateTime(DateUtils.getNowDate());
        return ivrLibaExtemplateMapper.insertIvrLibaExtemplate(ivrLibaExtemplate);
        Boolean i = ivrLibaExtemplateMapper.insertIvrLibaExtemplate(ivrLibaExtemplate);
        if (i) {
            return ivrLibaExtemplate;
        }
        return null;
    }
    /**
@@ -73,7 +78,7 @@
     * @return ç»“æžœ
     */
    @Override
    public int deleteIvrLibaExtemplateByIDs(String[] IDs) {
    public int deleteIvrLibaExtemplateByIDs(Long[] IDs) {
        return ivrLibaExtemplateMapper.deleteIvrLibaExtemplateByIDs(IDs);
    }
@@ -84,7 +89,7 @@
     * @return ç»“æžœ
     */
    @Override
    public int deleteIvrLibaExtemplateByID(String ID) {
    public int deleteIvrLibaExtemplateByID(Long ID) {
        return ivrLibaExtemplateMapper.deleteIvrLibaExtemplateByID(ID);
    }
}
smartor/src/main/java/com/smartor/service/impl/IvrLibaExtemplatescriptServiceImpl.java
@@ -1,9 +1,14 @@
package com.smartor.service.impl;
import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.smartor.domain.IvrLibaExtemplatescript;
import com.smartor.mapper.IvrLibaExtemplatescriptMapper;
import com.smartor.service.IIvrLibaExtemplatescriptService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -39,7 +44,26 @@
     */
    @Override
    public List<IvrLibaExtemplatescript> selectIvrLibaExtemplatescriptList(IvrLibaExtemplatescript ivrLibaExtemplatescript) {
        return ivrLibaExtemplatescriptMapper.selectIvrLibaExtemplatescriptList(ivrLibaExtemplatescript);
        List<IvrLibaExtemplatescript> ivrLibaExtemplatescripts = ivrLibaExtemplatescriptMapper.selectIvrLibaExtemplatescriptList(ivrLibaExtemplatescript);
        ObjectMapper mapper = new ObjectMapper();
        for (IvrLibaExtemplatescript ivrLibaExtemplatescript1 : ivrLibaExtemplatescripts) {
            if (!StringUtils.isEmpty(ivrLibaExtemplatescript1.getDynamiccruxsJson())) {
                try {
                    ivrLibaExtemplatescript1.setDynamiccruxs(mapper.readValue(ivrLibaExtemplatescript1.getDynamiccruxsJson(), List.class));
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            }
            if (!StringUtils.isEmpty(ivrLibaExtemplatescript1.getNodynamiccruxsJson())) {
                try {
                    ivrLibaExtemplatescript1.setNodynamiccruxs(mapper.readValue(ivrLibaExtemplatescript1.getNodynamiccruxsJson(), List.class));
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            }
        }
        return ivrLibaExtemplatescripts;
    }
    /**
@@ -50,6 +74,10 @@
     */
    @Override
    public int insertIvrLibaExtemplatescript(IvrLibaExtemplatescript ivrLibaExtemplatescript) {
        if (CollectionUtils.isNotEmpty(ivrLibaExtemplatescript.getDynamiccruxs()))
            ivrLibaExtemplatescript.setDynamiccruxsJson(JSON.toJSONString(ivrLibaExtemplatescript.getDynamiccruxs()));
        if (CollectionUtils.isNotEmpty(ivrLibaExtemplatescript.getNodynamiccruxs()))
            ivrLibaExtemplatescript.setNodynamiccruxsJson(JSON.toJSONString(ivrLibaExtemplatescript.getNodynamiccruxs()));
        ivrLibaExtemplatescript.setCreateTime(DateUtils.getNowDate());
        return ivrLibaExtemplatescriptMapper.insertIvrLibaExtemplatescript(ivrLibaExtemplatescript);
    }
@@ -63,6 +91,10 @@
    @Override
    public int updateIvrLibaExtemplatescript(IvrLibaExtemplatescript ivrLibaExtemplatescript) {
        ivrLibaExtemplatescript.setUpdateTime(DateUtils.getNowDate());
        if (CollectionUtils.isNotEmpty(ivrLibaExtemplatescript.getDynamiccruxs()))
            ivrLibaExtemplatescript.setDynamiccruxsJson(JSON.toJSONString(ivrLibaExtemplatescript.getDynamiccruxs()));
        if (CollectionUtils.isNotEmpty(ivrLibaExtemplatescript.getNodynamiccruxs()))
            ivrLibaExtemplatescript.setNodynamiccruxsJson(JSON.toJSONString(ivrLibaExtemplatescript.getNodynamiccruxs()));
        return ivrLibaExtemplatescriptMapper.updateIvrLibaExtemplatescript(ivrLibaExtemplatescript);
    }
@@ -73,7 +105,7 @@
     * @return ç»“æžœ
     */
    @Override
    public int deleteIvrLibaExtemplatescriptByIDs(String[] IDs) {
    public int deleteIvrLibaExtemplatescriptByIDs(Long[] IDs) {
        return ivrLibaExtemplatescriptMapper.deleteIvrLibaExtemplatescriptByIDs(IDs);
    }
@@ -84,7 +116,7 @@
     * @return ç»“æžœ
     */
    @Override
    public int deleteIvrLibaExtemplatescriptByID(String ID) {
    public int deleteIvrLibaExtemplatescriptByID(Long ID) {
        return ivrLibaExtemplatescriptMapper.deleteIvrLibaExtemplatescriptByID(ID);
    }
}
smartor/src/main/java/com/smartor/service/impl/IvrLibaScriptServiceImpl.java
@@ -1,8 +1,12 @@
package com.smartor.service.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DtoConversionUtils;
import com.ruoyi.common.utils.StringUtils;
import com.smartor.domain.*;
import com.smartor.mapper.IvrLibaScriptMapper;
import com.smartor.mapper.IvrLibaScriptTagMapper;
@@ -87,6 +91,19 @@
        IvrLibaScriptTargetoption ivrLibaScriptTargetoption = new IvrLibaScriptTargetoption();
        ivrLibaScriptTargetoption.setScriptid(ivrLibaScripts.get(0).getId());
        List<IvrLibaScriptTargetoption> ivrLibaScriptTargetoptions = ivrLibaScriptTargetoptionMapper.selectIvrLibaScriptTargetoptionList(ivrLibaScriptTargetoption);
        for (IvrLibaScriptTargetoption ivrLibaScriptTargetoption1 : ivrLibaScriptTargetoptions) {
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                if (StringUtils.isNotEmpty(ivrLibaScriptTargetoption1.getDynamiccruxsJson()))
                    ivrLibaScriptTargetoption1.setDynamiccruxs(objectMapper.readValue(ivrLibaScriptTargetoption1.getDynamiccruxsJson(), List.class));
                if (StringUtils.isNotEmpty(ivrLibaScriptTargetoption1.getNodynamiccruxsJson()))
                    ivrLibaScriptTargetoption1.setNodynamiccruxs(objectMapper.readValue(ivrLibaScriptTargetoption1.getNodynamiccruxsJson(), List.class));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        scriptVO.setIvrLibaScriptTargetoptionList(ivrLibaScriptTargetoptions);
//        //查询问题指标接口
@@ -119,31 +136,17 @@
        if (ivrLibaScript.getId() == null) {
            throw new BaseException("话术ID为空,请检查话术入参信息是否完整");
        }
//        //对问题指标进行处理
//        if (CollectionUtils.isNotEmpty(ivrLibaScriptVO.getIvrLibaScriptTargetList())) {
//            for (IvrLibaScriptTarget ivrLibaScriptTarget : ivrLibaScriptVO.getIvrLibaScriptTargetList()) {
//                if (ivrLibaScriptTarget.getIsoperation() != null && ivrLibaScriptTarget.getIsoperation() == 1) {
//                    //新增
//                    ivrLibaScriptTarget.setScriptid(ivrLibaScript.getId());
//                    ivrLibaScriptTargetMapper.insertIvrLibaScriptTarget(ivrLibaScriptTarget);
//                } else if (ivrLibaScriptTarget.getIsoperation() != null && ivrLibaScriptTarget.getIsoperation() == 2) {
//                    //修改
//                    ivrLibaScriptTarget.setScriptid(ivrLibaScript.getId());
//                    ivrLibaScriptTargetMapper.updateIvrLibaScriptTarget(ivrLibaScriptTarget);
//                } else if (ivrLibaScriptTarget.getIsoperation() != null && ivrLibaScriptTarget.getIsoperation() == 3) {
//                    //删除
//                    if (ivrLibaScriptTarget.getId() == null) {
//                        log.info("删除失败,问题指标id为空");
//                    } else {
//                        ivrLibaScriptTargetMapper.deleteIvrLibaScriptTargetByQuestionTargetID(ivrLibaScriptTarget.getId());
//                    }
//                }
//            }
//        }
        //对问题指标选项进行处理
        if (CollectionUtils.isNotEmpty(ivrLibaScriptVO.getIvrLibaScriptTargetoptionList())) {
            for (IvrLibaScriptTargetoption ivrLibaScriptTargetoption : ivrLibaScriptVO.getIvrLibaScriptTargetoptionList()) {
                if (CollectionUtils.isNotEmpty(ivrLibaScriptTargetoption.getNodynamiccruxs())) {
                    ivrLibaScriptTargetoption.setNodynamiccruxsJson(new Gson().toJson(ivrLibaScriptTargetoption.getNodynamiccruxs()));
                }
                if (CollectionUtils.isNotEmpty(ivrLibaScriptTargetoption.getDynamiccruxs())) {
                    ivrLibaScriptTargetoption.setDynamiccruxsJson(new Gson().toJson(ivrLibaScriptTargetoption.getDynamiccruxs()));
                }
                if (ivrLibaScriptTargetoption.getIsoperation() != null && ivrLibaScriptTargetoption.getIsoperation() == 1) {
                    //新增
                    ivrLibaScriptTargetoption.setScriptid(ivrLibaScript.getId());
smartor/src/main/java/com/smartor/service/impl/IvrLibaTargetServiceImpl.java
@@ -1,7 +1,11 @@
package com.smartor.service.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DtoConversionUtils;
import com.ruoyi.common.utils.StringUtils;
import com.smartor.domain.*;
import com.smartor.mapper.IvrLibaTargetMapper;
import com.smartor.mapper.IvrLibaTargetTagMapper;
@@ -66,6 +70,17 @@
            //获取该指标的选项
            List<IvrLibaTargetoption> ivrLibaTargetoptions = ivrLibaTargetoptionMapper.selectIvrLibaTargetoptionList(ivrLibaTargetoption);
            if (CollectionUtils.isNotEmpty(ivrLibaTargetoptions)) {
                for (IvrLibaTargetoption ivrLibaTargetoption1 : ivrLibaTargetoptions) {
                    ObjectMapper objectMapper = new ObjectMapper();
                    try {
                        if (StringUtils.isNotEmpty(ivrLibaTargetoption1.getDynamiccruxsJson()))
                            ivrLibaTargetoption1.setDynamiccruxs(objectMapper.readValue(ivrLibaTargetoption1.getDynamiccruxsJson(), List.class));
                        if (StringUtils.isNotEmpty(ivrLibaTargetoption1.getNodynamiccruxsJson()))
                            ivrLibaTargetoption1.setNodynamiccruxs(objectMapper.readValue(ivrLibaTargetoption1.getNodynamiccruxsJson(), List.class));
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }
                }
                ivrLibaTarget1.setTargetoptionList(ivrLibaTargetoptions);
            }
            //获取该指标的标签
@@ -152,6 +167,13 @@
        }
        if (CollectionUtils.isNotEmpty(ivrLibaTargetVO.getTargetoptionList())) {
            for (IvrLibaTargetoption ivrLibaTargetoption : ivrLibaTargetVO.getTargetoptionList()) {
                if (CollectionUtils.isNotEmpty(ivrLibaTargetoption.getNodynamiccruxs())) {
                    ivrLibaTargetoption.setNodynamiccruxsJson(new Gson().toJson(ivrLibaTargetoption.getNodynamiccruxs()));
                }
                if (CollectionUtils.isNotEmpty(ivrLibaTargetoption.getDynamiccruxs())) {
                    ivrLibaTargetoption.setDynamiccruxsJson(new Gson().toJson(ivrLibaTargetoption.getDynamiccruxs()));
                }
                if (ivrLibaTargetoption.getIsoperation() != null && ivrLibaTargetoption.getIsoperation() == 1) {
                    //新增
                    ivrLibaTargetoption.setTargetid(ivrLibaTarget.getId());
@@ -174,7 +196,6 @@
    /**
     * æ‰¹é‡åˆ é™¤æŒ‡æ ‡é€‰é¡¹åº“
     *
     * @param targetIDs éœ€è¦åˆ é™¤çš„æŒ‡æ ‡é€‰é¡¹åº“主键
     * @return ç»“æžœ
     */
    @Override
@@ -185,7 +206,6 @@
    /**
     * åˆ é™¤æŒ‡æ ‡é€‰é¡¹åº“信息
     *
     * @param targetID æŒ‡æ ‡é€‰é¡¹åº“主键
     * @return ç»“æžœ
     */
    @Override
smartor/src/main/java/com/smartor/service/impl/IvrLibaTemplateServiceImpl.java
@@ -1,8 +1,13 @@
package com.smartor.service.impl;
import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DtoConversionUtils;
import com.ruoyi.common.utils.StringUtils;
import com.smartor.domain.*;
import com.smartor.mapper.*;
import com.smartor.service.IIvrLibaTemplateService;
@@ -11,8 +16,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.*;
/**
 * æ¨¡æ¿åº“Service业务层处理
@@ -227,11 +231,19 @@
                    //新增
                    ivrLibaTemplateTargetoption.setTemplateID(tmpID);
                    ivrLibaTemplateTargetoption.setScriptid(ivrLibaTemplateScript.getID());
                    if (CollectionUtils.isNotEmpty(ivrLibaTemplateTargetoption.getDynamiccruxs()))
                        ivrLibaTemplateTargetoption.setDynamiccruxsJson(JSON.toJSONString(ivrLibaTemplateTargetoption.getDynamiccruxs()));
                    if (CollectionUtils.isNotEmpty(ivrLibaTemplateTargetoption.getNodynamiccruxs()))
                        ivrLibaTemplateTargetoption.setNodynamiccruxsJson(JSON.toJSONString(ivrLibaTemplateTargetoption.getNodynamiccruxs()));
                    ivrLibaTemplateTargetOptionMapper.insertIvrLibaTemplateTargetoption(ivrLibaTemplateTargetoption);
                } else if (ivrLibaTemplateTargetoption.getIsoperation() != null && ivrLibaTemplateTargetoption.getIsoperation() == 2) {
                    //修改
                    ivrLibaTemplateTargetoption.setTemplateID(tmpID);
                    ivrLibaTemplateTargetoption.setScriptid(ivrLibaTemplateScript.getID());
                    if (CollectionUtils.isNotEmpty(ivrLibaTemplateTargetoption.getDynamiccruxs()))
                        ivrLibaTemplateTargetoption.setDynamiccruxsJson(JSON.toJSONString(ivrLibaTemplateTargetoption.getDynamiccruxs()));
                    if (CollectionUtils.isNotEmpty(ivrLibaTemplateTargetoption.getNodynamiccruxs()))
                        ivrLibaTemplateTargetoption.setNodynamiccruxsJson(JSON.toJSONString(ivrLibaTemplateTargetoption.getNodynamiccruxs()));
                    ivrLibaTemplateTargetOptionMapper.updateIvrLibaTemplateTargetoption(ivrLibaTemplateTargetoption);
                } else if (ivrLibaTemplateTargetoption.getIsoperation() != null && ivrLibaTemplateTargetoption.getIsoperation() == 3) {
                    //删除
@@ -280,9 +292,28 @@
            IvrLibaTemplateTargetoption ivrLibaTemplateTargetoption = new IvrLibaTemplateTargetoption();
            ivrLibaTemplateTargetoption.setScriptid(ivrLibaTemplateScriptVO.getID());
            List<IvrLibaTemplateTargetoption> ivrLibaTemplateTargetoptions = ivrLibaTemplateTargetOptionMapper.selectIvrLibaTemplateTargetoptionList(ivrLibaTemplateTargetoption);
            ivrLibaTemplateScriptVO.setIvrLibaScriptTargetoptionList(ivrLibaTemplateTargetoptions);
            for (IvrLibaTemplateTargetoption ivrLibaTemplateTargetoption1 : ivrLibaTemplateTargetoptions) {
                ObjectMapper mapper = new ObjectMapper();
                if (!StringUtils.isEmpty(ivrLibaTemplateTargetoption1.getDynamiccruxsJson())) {
                    try {
                        ivrLibaTemplateTargetoption1.setDynamiccruxs(mapper.readValue(ivrLibaTemplateTargetoption1.getDynamiccruxsJson(), List.class));
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }
        }
                if (!StringUtils.isEmpty(ivrLibaTemplateTargetoption1.getNodynamiccruxsJson())) {
                    try {
                        ivrLibaTemplateTargetoption1.setNodynamiccruxs(mapper.readValue(ivrLibaTemplateTargetoption1.getNodynamiccruxsJson(), List.class));
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }
                }
            }
            ivrLibaTemplateScriptVO.setIvrLibaScriptTargetoptionList(ivrLibaTemplateTargetoptions);
        }
        Collections.sort(ivrLibaTemplateScriptVOS, Comparator.comparing(IvrLibaTemplateScriptVO::getTargetid));
        //数据组装
        templateVO.setIvrLibaTemplateTagList(ivrLibaTemplateTags);
        templateVO.setIvrLibaTemplateScriptVOList(ivrLibaTemplateScriptVOS);
smartor/src/main/java/com/smartor/service/impl/IvrTaskcallServiceImpl.java
@@ -1,21 +1,37 @@
package com.smartor.service.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DtoConversionUtils;
//import com.smartor.config.PhoneUtils;
import com.smartor.config.PhoneUtils;
import com.smartor.config.RabbitMqConfig;
import com.smartor.domain.*;
import com.smartor.mapper.IvrLibaExtemplatescriptMapper;
import com.smartor.mapper.IvrLibaTemplateTargetoptionMapper;
import com.smartor.mapper.IvrTaskcallMapper;
import com.smartor.mapper.PatTaskRelevanceMapper;
import com.smartor.service.IIvrTaskcallService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * å•一任务(随访)Service业务层处理
@@ -30,7 +46,17 @@
    private IvrTaskcallMapper ivrTaskcallMapper;
    @Autowired
    private PatTaskRelevanceMapper patTaskRelevanceMapper;
    private IvrLibaTemplateTargetoptionMapper ivrLibaScriptTargetoptionMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private IvrLibaExtemplatescriptMapper ivrLibaExtemplatescriptMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * æŸ¥è¯¢å•一任务(随访)
@@ -103,8 +129,8 @@
    @Override
    public int insertOrUpdateTask(IvrTaskcallVO ivrTaskcallVO) {
        if (ObjectUtils.isEmpty(ivrTaskcallVO)) {
            log.info("宣教任务入参为空,请检查入参");
            throw new BaseException("宣教任务入参为空,请检查入参");
            log.info("任务入参为空,请检查入参");
            throw new BaseException("任务入参为空,请检查入参");
        }
        Integer integer = 0;
        if (ivrTaskcallVO.getIsoperation() != null && ivrTaskcallVO.getIsoperation() == 1) {
@@ -120,6 +146,9 @@
                    ivrTaskcall.setAddr(patTaskRelevance.getAddr());
                    ivrTaskcall.setCreateTime(DateUtils.getNowDate());
                    ivrTaskcall.setTextParam(new Gson().toJson(ivrTaskcallVO.getTextParam()));
                    if (CollectionUtils.isNotEmpty(ivrTaskcallVO.getSendTimeslot())) {
                        ivrTaskcall.setSendTimeSlot(ivrTaskcallVO.getSendTimeslot().toString());
                    }
                    ivrTaskcallMapper.insertIvrTaskcall(ivrTaskcall);
                    integer = ivrTaskcall.getId().intValue();
                }
@@ -135,8 +164,10 @@
                    ivrTaskcall.setPhone(patTaskRelevance.getPhone());
                    ivrTaskcall.setAddr(patTaskRelevance.getAddr());
                    ivrTaskcall.setCreateTime(DateUtils.getNowDate());
                    if (CollectionUtils.isNotEmpty(ivrTaskcallVO.getSendTimeslot())) {
                        ivrTaskcall.setSendTimeSlot(ivrTaskcallVO.getSendTimeslot().toString());
                    }
                    ivrTaskcall.setTextParam(new Gson().toJson(ivrTaskcallVO.getTextParam()));
                    ivrTaskcallMapper.updateIvrTaskcall(ivrTaskcall);
                    integer = ivrTaskcall.getId().intValue();
                }
@@ -150,4 +181,307 @@
        return integer;
    }
    /**
     * ä»»åŠ¡å‘é€
     *
     * @return
     */
    @Override
    public int heTaskSend(IvrTaskcallVO ivrTaskcallVO) {
        //判断任务是否是立即发送
        if (ivrTaskcallVO.getSendType().equals("2") && ivrTaskcallVO.getSendstate() == 1) {
            IvrTaskcallMQ ivrTaskcallMQ = new IvrTaskcallMQ();
            ivrTaskcallMQ.setTaskid(ivrTaskcallVO.getTaskid());
            ivrTaskcallMQ.setSendType("1");
            ivrTaskcallMQ.setTemplateid(ivrTaskcallVO.getTemplateid());
            //立即发送
            rabbitTemplate.convertAndSend(RabbitMqConfig.phone_exchange, RabbitMqConfig.routing_key, new Gson().toJson(ivrTaskcallMQ), message -> {
                //注意这里时间可以使long,而且是设置header
                message.getMessageProperties().setHeader("x-delay", 0);
                return message;
            });
        } else if (ivrTaskcallVO.getSendType().equals("2") && ivrTaskcallVO.getSendstate() == 1) {
            //时间段发送
            if (CollectionUtils.isNotEmpty(ivrTaskcallVO.getSendTimeslot())) {
                for (TaskSendTimeVO taskSendTimeVO : ivrTaskcallVO.getSendTimeslot()) {
                    List<TaskSendTimeVO> list = new ArrayList<>();
                    list.add(taskSendTimeVO);
                    //获取开始发送时间
                    String begantime = taskSendTimeVO.getBegantime();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    //记录目前到发送时间的毫秒值 ï¼ˆå‘送时间的毫秒值 - å½“前时间的毫秒值)
                    Long milliseconds = 1000L;
                    try {
                        Date date = sdf.parse(begantime);
                        milliseconds = date.getTime() - System.currentTimeMillis();
                        System.out.println("日期毫秒数:" + milliseconds);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    IvrTaskcallMQ ivrTaskcallMQ = new IvrTaskcallMQ();
                    ivrTaskcallMQ.setTaskid(ivrTaskcallVO.getTaskid());
                    ivrTaskcallMQ.setSendType("2");
                    ivrTaskcallMQ.setTemplateid(ivrTaskcallVO.getTemplateid());
                    ivrTaskcallMQ.setSendTimeslot(list);
                    Long finalMilliseconds = milliseconds;
                    rabbitTemplate.convertAndSend(RabbitMqConfig.phone_exchange, RabbitMqConfig.routing_key, new Gson().toJson(ivrTaskcallMQ), message -> {
                        //注意这里时间可以使long,而且是设置header
                        message.getMessageProperties().setHeader("x-delay", finalMilliseconds);
                        return message;
                    });
                }
            }
        }
        return 0;
    }
    @Override
    public PhoneCallBackVO phoneCallBack(PhoneCallBackVO phoneCallBackVO) {
        log.info("phoneCallBackVO的入参:{},{},{},{},{},{},{}", phoneCallBackVO.getResultType(), phoneCallBackVO.getUuid(), phoneCallBackVO.getErrResult(), phoneCallBackVO.getTextResult(), phoneCallBackVO.getHangUpResult(), phoneCallBackVO.getEnumState(), phoneCallBackVO.getUint8());
        //获取数据
        Boolean aBoolean = redisCache.hasKey(phoneCallBackVO.getUuid());
        if (!aBoolean) {
            new BaseException("该uuid不存在");
        }
        Integer hangupValue = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "hangup");
        if (hangupValue != null && hangupValue == 1) {
            //hangupValue == 1  éšè®¿ç»“束,直接可以挂电话
            PhoneUtils phoneUtils = new PhoneUtils();
            phoneUtils.hangup(phoneCallBackVO.getUuid(), null, null, null, null, null, null, null);
        }
        String cacheObject = redisCache.getCacheObject(phoneCallBackVO.getUuid());
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> map = null;
        try {
            map = objectMapper.readValue(cacheObject, Map.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        IvrTaskcall ivrTaskcall = (IvrTaskcall) map.get("ivrTaskcall");
        List<IvrLibaTemplateScriptVO> ivrLibaTemplateScriptVOs = (List<IvrLibaTemplateScriptVO>) map.get("ivrLibaTemplateScriptVO");
        //将uuid更新到数据库中
        ivrTaskcall.setSenduuid(phoneCallBackVO.getUuid());
        ivrTaskcallMapper.updateIvrTaskcall(ivrTaskcall);
        //获取模板信息
        IvrLibaTemplateVO ivrLibaTemplateVO = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "ivrLibaTemplateVO");
        //首先判断resultType
        if (phoneCallBackVO.getResultType() == 1) {
            //呼叫结果接口: 1
            if (phoneCallBackVO.getUint8() == 1) {
                //呼叫失败,去redis中记录一下失败次数,进行再次呼叫
                Integer integer = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "uint8");
                if (integer != null) {
                    redisCache.setCacheObject(phoneCallBackVO.getUuid() + "uint8", integer + 1, 120, TimeUnit.MINUTES);
                } else {
                    redisCache.setCacheObject(phoneCallBackVO.getUuid() + "uint8", 1, 120, TimeUnit.MINUTES);
                }
                if (integer != null && integer == ivrTaskcall.getRecallcount().intValue()) {
                    log.info("无人接听:{},   {}", phoneCallBackVO.getErrResult(), phoneCallBackVO.getUuid());
                    //连续打规定次,如果要没人接,那就结束
                    ivrTaskcall.setResult(phoneCallBackVO.getErrResult());
                    ivrTaskcallMapper.updateIvrTaskcall(ivrTaskcall);
                    redisCache.deleteObject(phoneCallBackVO.getUuid() + "uint8");
                } else if (integer != null && integer < ivrTaskcall.getRecallcount().intValue()) {
                    //进行重拨
                    PhoneUtils phoneUtils = new PhoneUtils();
                    phoneUtils.ob(phoneCallBackVO.getUuid(), null, ivrTaskcall.getPhone(), null, null, null, null, null, null, null, null);
                }
            }
        } else if (phoneCallBackVO.getResultType() == 2) {
            //通话状态更新接口: 2
            if (phoneCallBackVO.getEnumState() == 0) {
                // 0-振铃
                Integer integer = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "enumState");
                if (integer != null && integer < ivrTaskcall.getRecallcount().intValue()) {
                    redisCache.setCacheObject(phoneCallBackVO.getUuid() + "enumState", integer + 1, 120, TimeUnit.MINUTES);
                } else if (integer == null) {
                    redisCache.setCacheObject(phoneCallBackVO.getUuid() + "enumState", 1, 120, TimeUnit.MINUTES);
                } else if (integer != null && integer == ivrTaskcall.getRecallcount().intValue()) {
                    ivrTaskcall.setResult("无人接听");
                    ivrTaskcallMapper.updateIvrTaskcall(ivrTaskcall);
                    redisCache.deleteObject(phoneCallBackVO.getUuid() + "enumState");
                }
            } else if (phoneCallBackVO.getEnumState() == 2) {
                //患者挂断电话
                log.info("患者挂断电话:{}", phoneCallBackVO.getUuid());
                ivrTaskcall.setResult(phoneCallBackVO.getHangUpResult());
                ivrTaskcallMapper.updateIvrTaskcall(ivrTaskcall);
                redisCache.deleteObject(phoneCallBackVO.getUuid() + "enumState");
            }
        } else if (phoneCallBackVO.getResultType() == 3) {
            //语音识别结果上报接口: 3
            Integer noVoice = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "noVoice");
            QuestionMessage returnQues = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "returnQues");
            IvrLibaTemplateScriptVO nowQuestion = returnQues.getNowQuestion();
            PhoneUtils phoneUtils = new PhoneUtils();
            if (StringUtils.isEmpty(phoneCallBackVO.getTextResult())) {
                //无回话
                //判断noVoice是否已经到了最大值
                if (noVoice == ivrLibaTemplateVO.getNoVoiceNum().intValue()) {
                    //已经问了对应的遍数,就判断是否还有下一题
                    if (nowQuestion.getTargetid() == ivrLibaTemplateScriptVOs.size()) {
                        //没有下一题了,就挂断电话,播放结束语
                        redisCache.setCacheObject(phoneCallBackVO.getUuid() + "hangup", 1, 120, TimeUnit.MINUTES);
                        phoneUtils.ttsPlayback(ivrLibaTemplateVO.getRevisitAfter(), phoneCallBackVO.getUuid());
                    } else {
                        //有下一题
                        redisCache.setCacheObject(phoneCallBackVO.getUuid() + "noVoice", 0, 120, TimeUnit.MINUTES);
                        IvrLibaTemplateScriptVO nextQuestion = getNextQuestion(ivrLibaTemplateScriptVOs, nowQuestion);
                        // é—®é¢˜ï¼Œ  åŽ»è°ƒç”¨â€œtts合成和播放”接口
                        phoneUtils.ttsPlayback(nowQuestion.getQuestionText(), phoneCallBackVO.getUuid());
                    }
                } else {
                    redisCache.setCacheObject(phoneCallBackVO.getUuid() + "noVoice", noVoice + 1, 120, TimeUnit.MINUTES);
                    //调用ivrLibaTemplateScriptVO中的slienceText(静默话术)
                    String slienceText = nowQuestion.getSlienceText();
                    //静默话术  + é—®é¢˜ï¼Œ  åŽ»è°ƒç”¨â€œtts合成和播放”接口
                    phoneUtils.ttsPlayback(slienceText + nowQuestion.getQuestionText(), phoneCallBackVO.getUuid());
                    return new PhoneCallBackVO();
                }
            } else {
                //有回话,对回答的问题,进行正则匹配(这里只针对选择题,其它题型不行)
                for (int j = 0; j < nowQuestion.getIvrLibaScriptTargetoptionList().size(); j++) {
                    //包含
                    Matcher matcher = null;
                    if (StringUtils.isNotEmpty(nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getTargetregex())) {
                        Pattern pattern = Pattern.compile(nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getTargetregex());
                        matcher = pattern.matcher(phoneCallBackVO.getTextResult());
                    }
                    //不包含
                    Matcher matcher2 = null;
                    if (StringUtils.isNotEmpty(nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getTargetregex2())) {
                        Pattern pattern2 = Pattern.compile(nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getTargetregex2());
                        matcher2 = pattern2.matcher(phoneCallBackVO.getTextResult());
                    }
                    log.info("phoneCallBack--Targetregex的值为:{}, phoneCallBack--Targetregex2的值为:{}", nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getTargetregex(), nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getTargetregex2());
                    if (StringUtils.isNotEmpty(nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getTargetregex()) && matcher.matches() && StringUtils.isNotEmpty(nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getTargetregex2()) && matcher2.matches() || StringUtils.isEmpty(nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getTargetregex()) && StringUtils.isNotEmpty(nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getTargetregex2()) && matcher2.matches() || StringUtils.isEmpty(nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getTargetregex2()) && StringUtils.isNotEmpty(nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getTargetregex()) && matcher.matches()) {
                        //说明匹配正确了
                        //这里应该先判断类型,去再修改,设置IsUserOperation是单选题的改法
                        nowQuestion.getIvrLibaScriptTargetoptionList().get(j).setIsUserOperation(true);
                        ivrLibaScriptTargetoptionMapper.updateIvrLibaTemplateTargetoption(nowQuestion.getIvrLibaScriptTargetoptionList().get(j));
                        //将静默置为0
                        redisCache.setCacheObject(phoneCallBackVO.getUuid() + "noVoice", 0, 120, TimeUnit.MINUTES);
                        redisCache.setCacheObject(phoneCallBackVO.getUuid() + "mateNum", 0, 120, TimeUnit.MINUTES);
                        //获取下一题
                        Integer nextQuestion = nowQuestion.getIvrLibaScriptTargetoptionList().get(j).getNextQuestion();
                        for (IvrLibaTemplateScriptVO script : ivrLibaTemplateScriptVOs) {
                            if (script.getTargetid() == nextQuestion) {
                                QuestionMessage questionMessage = new QuestionMessage();
                                questionMessage.setNowQuestion(script);
                                questionMessage.setQuestionList(ivrLibaTemplateScriptVOs);
                                redisCache.setCacheObject(phoneCallBackVO.getUuid() + "returnQues", questionMessage, 120, TimeUnit.MINUTES);
                                break;
                            }
                        }
                        break;
                    } else {
                        //没有匹配到
                        Integer mateNum = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "mateNum");
                        //无匹配次数去判断是否到最大询问次数,并且所有的选项都匹配完了
                        if (mateNum == ivrLibaTemplateVO.getMateNum().intValue() && j == nowQuestion.getIvrLibaScriptTargetoptionList().size() - 1) {
                            //如果下一题为空.则新的数据返回,并加上感谢语
                            if (nowQuestion.getTargetid() < ivrLibaTemplateScriptVOs.size()) {
                                QuestionMessage questionMessage = new QuestionMessage();
                                IvrLibaTemplateScriptVO nextQuestion = getNextQuestion(ivrLibaTemplateScriptVOs, nowQuestion);
                                questionMessage.setQuestionList(ivrLibaTemplateScriptVOs);
                                questionMessage.setNowQuestion(nextQuestion);
                                redisCache.setCacheObject(phoneCallBackVO.getUuid() + "returnQues", questionMessage, 120, TimeUnit.MINUTES);
                                redisCache.setCacheObject(phoneCallBackVO.getUuid() + "mateNum", 0, 120, TimeUnit.MINUTES);
                            } else {
                                //就可以挂断电话了
                                redisCache.setCacheObject(phoneCallBackVO.getUuid() + "hangup", 1, 120, TimeUnit.MINUTES);
                                phoneUtils.ttsPlayback(ivrLibaTemplateVO.getRevisitAfter(), phoneCallBackVO.getUuid());
                                break;
                            }
                        } else if (mateNum < ivrLibaTemplateVO.getMateNum().intValue() && j == nowQuestion.getIvrLibaScriptTargetoptionList().size() - 1) {
                            //没有问到规定次数
                            mateNum = mateNum + 1;
                            redisCache.setCacheObject(phoneCallBackVO.getUuid() + "mateNum", mateNum, 120, TimeUnit.MINUTES);
                        }
                    }
                }
                //选项匹配完成后,需要再去通过库再进行匹配一次
                String extemplateID = ivrLibaTemplateVO.getSubmoduleID();
                String[] split = extemplateID.split(",");
                List<String> list = Arrays.asList(split);
                List<Long> list1 = new ArrayList<>();
                if (StringUtils.isNotEmpty(extemplateID)) {
                    for (String str : list) {
                        list1.add(Long.valueOf(str));
                    }
                    List<IvrLibaExtemplatescript> ivrLibaExtemplatescripts = ivrLibaExtemplatescriptMapper.queryIvrLibaExtemplatescriptList(list1);
                    for (IvrLibaExtemplatescript ivrLibaExtemplatescript : ivrLibaExtemplatescripts) {
                        Matcher matcher = null;
                        if (StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex())) {
                            Pattern pattern = Pattern.compile(ivrLibaExtemplatescript.getSelfRegex());
                            matcher = pattern.matcher(returnQues.getContent());
                        }
                        Matcher matcher2 = null;
                        if (StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex2())) {
                            Pattern pattern2 = Pattern.compile(ivrLibaExtemplatescript.getSelfRegex2());
                            matcher2 = pattern2.matcher(returnQues.getContent());
                        }
                        log.info("++++++++++++++++++++++++++通用库是否为空:selfRegex : {} , selfRegex2 : {}", ivrLibaExtemplatescript.getSelfRegex(), ivrLibaExtemplatescript.getSelfRegex2());
                        if (StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex()) && matcher.matches() && StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex2()) && matcher2.matches() || StringUtils.isEmpty(ivrLibaExtemplatescript.getSelfRegex()) && StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex2()) && matcher2.matches() || StringUtils.isEmpty(ivrLibaExtemplatescript.getSelfRegex2()) && StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex()) && matcher.matches()) {
                            QuestionMessage questionMessage = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "returnQues");
                            IvrLibaTemplateScriptVO ivrLibaTemplateScriptVO = returnQues.getNowQuestion();
                            ivrLibaTemplateScriptVO.setSubmoduleText(ivrLibaExtemplatescript.getSwitchText());
                            ivrLibaTemplateScriptVO.setSubmoduleVoice(ivrLibaExtemplatescript.getSwitchWav());
                            redisCache.setCacheObject(phoneCallBackVO.getUuid() + "returnQues", questionMessage, 120, TimeUnit.MINUTES);
                            if (ivrLibaExtemplatescript.getIsEnd() == 1) {
                                //将问题置空
                                IvrLibaTemplateScriptVO nowQuestion1 = questionMessage.getNowQuestion();
                                nowQuestion1.setQuestionText(null);
                                nowQuestion1.setQuestionVoice(null);
                                questionMessage.setNowQuestion(nowQuestion1);
                                redisCache.setCacheObject(phoneCallBackVO.getUuid() + "returnQues", questionMessage, 120, TimeUnit.MINUTES);
                                redisCache.setCacheObject(phoneCallBackVO.getUuid() + "isOver", 1, 120, TimeUnit.MINUTES);
                            }
                            //调用“15、tts合成和播放, tts_playback”将结果传回
                        }
                        break;
                    }
                }
            }
        }
        return phoneCallBackVO;
    }
    private IvrLibaTemplateScriptVO getNextQuestion(List<IvrLibaTemplateScriptVO> ivrLibaTemplateScriptVOList, IvrLibaTemplateScriptVO ivrLibaTemplateScriptVO) {
        for (int j = 0; j < ivrLibaTemplateScriptVOList.size(); j++) {
            if (ivrLibaTemplateScriptVOList.get(j).getTargetid() == ivrLibaTemplateScriptVO.getTargetid() + 1) {
                // å¯¹è¯¥æ¡templateScriptVO进行处理
                return ivrLibaTemplateScriptVOList.get(j);
            }
        }
        return null;
    }
}
smartor/src/main/java/com/smartor/service/impl/PersonVoiceServiceImpl.java
@@ -18,6 +18,7 @@
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.smartor.domain.*;
import com.smartor.mapper.*;
@@ -90,9 +91,9 @@
    }
    @Override
    public String texttospeech(String textspeech) {
    public String texttospeech(String textspeech, String filePath) {
        this.accessToken();
        this.process2(textspeech);
        this.process2(textspeech, filePath);
        client.shutdown();
        return returnResult;
    }
@@ -399,11 +400,15 @@
    }
    private SpeechSynthesizerListener getSynthesizerListener() {
    private SpeechSynthesizerListener getSynthesizerListener(String filePath) {
        SpeechSynthesizerListener listener = null;
        try {
            if (StringUtils.isEmpty(filePath)) {
                filePath = "tts_test.wav";
            }
            String finalFilePath = filePath;
            listener = new SpeechSynthesizerListener() {
                File f = new File("tts_test.wav");
                File f = new File(finalFilePath);
                FileOutputStream fout = new FileOutputStream(f);
                private boolean firstRecvBinary = true;
@@ -449,11 +454,11 @@
    }
    public void process2(String text) {
    public void process2(String text, String filePath) {
        SpeechSynthesizer synthesizer = null;
        try {
            //创建实例,建立连接。
            synthesizer = new SpeechSynthesizer(client, getSynthesizerListener());
            synthesizer = new SpeechSynthesizer(client, getSynthesizerListener(filePath));
            synthesizer.setAppKey(appKey);
            //设置返回音频的编码格式
            synthesizer.setFormat(OutputFormatEnum.WAV);
smartor/src/main/resources/mapper/smartor/IvrLibaExtemplateMapper.xml
@@ -57,7 +57,6 @@
            keyProperty="ID">
        insert into ivr_liba_extemplate
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="ID != null">ID,</if>
            <if test="extName != null and extName != ''">extName,</if>
            <if test="language != null and language != ''">language,</if>
            <if test="note != null">note,</if>
@@ -76,7 +75,6 @@
            <if test="guid != null">guid,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="ID != null">#{ID},</if>
            <if test="extName != null and extName != ''">#{extName},</if>
            <if test="language != null and language != ''">#{language},</if>
            <if test="note != null">#{note},</if>
@@ -119,13 +117,13 @@
        where ID = #{ID}
    </update>
    <delete id="deleteIvrLibaExtemplateByID" parameterType="String">
    <delete id="deleteIvrLibaExtemplateByID" parameterType="Long">
        delete
        from ivr_liba_extemplate
        where ID = #{ID}
    </delete>
    <delete id="deleteIvrLibaExtemplateByIDs" parameterType="String">
    <delete id="deleteIvrLibaExtemplateByIDs" parameterType="Long">
        delete from ivr_liba_extemplate where ID in
        <foreach item="ID" collection="array" open="(" separator="," close=")">
            #{ID}
smartor/src/main/resources/mapper/smartor/IvrLibaExtemplatescriptMapper.xml
@@ -11,6 +11,7 @@
        <result property="switchText" column="switchText"/>
        <result property="switchWav" column="switchWav"/>
        <result property="selfRegex" column="selfRegex"/>
        <result property="selfRegex2" column="selfRegex2"/>
        <result property="isEnable" column="isEnable"/>
        <result property="delFlag" column="del_flag"/>
        <result property="updateBy" column="update_by"/>
@@ -21,7 +22,10 @@
        <result property="uploadTime" column="upload_time"/>
        <result property="orgid" column="orgid"/>
        <result property="pid" column="pid"/>
        <result property="isEnd" column="is_end"/>
        <result property="guid" column="guid"/>
        <result property="dynamiccruxsJson" column="dynamiccruxs"/>
        <result property="nodynamiccruxsJson" column="nodynamiccruxs"/>
    </resultMap>
    <sql id="selectIvrLibaExtemplatescriptVo">
@@ -31,6 +35,7 @@
               switchText,
               switchWav,
               selfRegex,
               selfRegex2,
               isEnable,
               del_flag,
               update_by,
@@ -41,6 +46,9 @@
               upload_time,
               orgid,
               pid,
               is_end,
               nodynamiccruxs,
               dynamiccruxs,
               guid
        from ivr_liba_extemplatescript
    </sql>
@@ -49,17 +57,33 @@
            resultMap="IvrLibaExtemplatescriptResult">
        <include refid="selectIvrLibaExtemplatescriptVo"/>
        <where>
            <if test="extID != null  and extID != ''">and extID = #{extID}</if>
            <if test="extID != null">and extID = #{extID}</if>
            <if test="switchID != null ">and switchID = #{switchID}</if>
            <if test="switchText != null  and switchText != ''">and switchText = #{switchText}</if>
            <if test="switchWav != null  and switchWav != ''">and switchWav = #{switchWav}</if>
            <if test="selfRegex != null  and selfRegex != ''">and selfRegex = #{selfRegex}</if>
            <if test="selfRegex2 != null  and selfRegex2 != ''">and selfRegex2 = #{selfRegex2}</if>
            <if test="isEnable != null ">and isEnable = #{isEnable}</if>
            <if test="isupload != null ">and isupload = #{isupload}</if>
            <if test="uploadTime != null ">and upload_time = #{uploadTime}</if>
            <if test="orgid != null  and orgid != ''">and orgid = #{orgid}</if>
            <if test="pid != null ">and pid = #{pid}</if>
            <if test="guid != null  and guid != ''">and guid = #{guid}</if>
            <if test="isEnd != null">and is_end = #{isEnd}</if>
        </where>
    </select>
    <select id="queryIvrLibaExtemplatescriptList" parameterType="com.smartor.domain.IvrLibaExtemplatescript"
            resultMap="IvrLibaExtemplatescriptResult">
        <include refid="selectIvrLibaExtemplatescriptVo"/>
        <where>
            del_flag = 0
            <if test="IDs != null">
                and extID in
                <foreach collection="IDs" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
        </where>
    </select>
@@ -68,16 +92,17 @@
        where ID = #{ID}
    </select>
    <insert id="insertIvrLibaExtemplatescript" parameterType="com.smartor.domain.IvrLibaExtemplatescript" useGeneratedKeys="true"
    <insert id="insertIvrLibaExtemplatescript" parameterType="com.smartor.domain.IvrLibaExtemplatescript"
            useGeneratedKeys="true"
            keyProperty="ID">
        insert into ivr_liba_extemplatescript
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="ID != null">ID,</if>
            <if test="extID != null and extID != ''">extID,</if>
            <if test="extID != null">extID,</if>
            <if test="switchID != null">switchID,</if>
            <if test="switchText != null">switchText,</if>
            <if test="switchWav != null">switchWav,</if>
            <if test="selfRegex != null">selfRegex,</if>
            <if test="selfRegex2 != null">selfRegex2,</if>
            <if test="isEnable != null">isEnable,</if>
            <if test="delFlag != null and delFlag != ''">del_flag,</if>
            <if test="updateBy != null">update_by,</if>
@@ -89,14 +114,17 @@
            <if test="orgid != null">orgid,</if>
            <if test="pid != null">pid,</if>
            <if test="guid != null">guid,</if>
            <if test="isEnd != null">is_end,</if>
            <if test="dynamiccruxsJson != null">dynamiccruxs,</if>
            <if test="nodynamiccruxsJson != null">nodynamiccruxs,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="ID != null">#{ID},</if>
            <if test="extID != null and extID != ''">#{extID},</if>
            <if test="extID != null ">#{extID},</if>
            <if test="switchID != null">#{switchID},</if>
            <if test="switchText != null">#{switchText},</if>
            <if test="switchWav != null">#{switchWav},</if>
            <if test="selfRegex != null">#{selfRegex},</if>
            <if test="selfRegex2 != null">#{selfRegex2},</if>
            <if test="isEnable != null">#{isEnable},</if>
            <if test="delFlag != null and delFlag != ''">#{delFlag},</if>
            <if test="updateBy != null">#{updateBy},</if>
@@ -108,17 +136,21 @@
            <if test="orgid != null">#{orgid},</if>
            <if test="pid != null">#{pid},</if>
            <if test="guid != null">#{guid},</if>
            <if test="isEnd != null">#{isEnd},</if>
            <if test="dynamiccruxsJson != null">#{dynamiccruxsJson},</if>
            <if test="nodynamiccruxsJson != null">#{nodynamiccruxsJson},</if>
        </trim>
    </insert>
    <update id="updateIvrLibaExtemplatescript" parameterType="com.smartor.domain.IvrLibaExtemplatescript">
        update ivr_liba_extemplatescript
        <trim prefix="SET" suffixOverrides=",">
            <if test="extID != null and extID != ''">extID = #{extID},</if>
            <if test="extID != null ">extID = #{extID},</if>
            <if test="switchID != null">switchID = #{switchID},</if>
            <if test="switchText != null">switchText = #{switchText},</if>
            <if test="switchWav != null">switchWav = #{switchWav},</if>
            <if test="selfRegex != null">selfRegex = #{selfRegex},</if>
            <if test="selfRegex2 != null">selfRegex2 = #{selfRegex2},</if>
            <if test="isEnable != null">isEnable = #{isEnable},</if>
            <if test="delFlag != null and delFlag != ''">del_flag = #{delFlag},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
@@ -130,11 +162,14 @@
            <if test="orgid != null">orgid = #{orgid},</if>
            <if test="pid != null">pid = #{pid},</if>
            <if test="guid != null">guid = #{guid},</if>
            <if test="isEnd != null">is_end = #{isEnd},</if>
            <if test="dynamiccruxsJson != null">dynamiccruxs = #{dynamiccruxsJson},</if>
            <if test="nodynamiccruxsJson != null">nodynamiccruxs = #{nodynamiccruxsJson},</if>
        </trim>
        where ID = #{ID}
    </update>
    <delete id="deleteIvrLibaExtemplatescriptByID" parameterType="String">
    <delete id="deleteIvrLibaExtemplatescriptByID" parameterType="Long">
        delete
        from ivr_liba_extemplatescript
        where ID = #{ID}
smartor/src/main/resources/mapper/smartor/IvrLibaTemplateMapper.xml
@@ -52,6 +52,7 @@
        <result property="mateNum" column="mate_num"/>
        <result property="revisitBefore" column="revisit_before"/>
        <result property="revisitAfter" column="revisit_after"/>
        <result property="noVoiceNum" column="no_voice_num"/>
    </resultMap>
    <sql id="selectIvrLibaTemplateVo">
@@ -72,6 +73,7 @@
               otherdata,
               suitway,
               mate_num,
               no_voice_num,
               submodule, language, note, isEnable, addUserID, addTime, modifyUserID, modifyTime, groupID, label_info, submoduleID, playType, icd10code, icd10codename, atuoTaskDayOffset, deptIds, dept_names, F_KSDM, del_flag, update_by, update_time, create_by, create_time, isupload, upload_time, orgid, pid, guid, assortid, parameter
        from ivr_liba_template
    </sql>
@@ -85,9 +87,10 @@
                '%')
            </if>
            <if test="targetid != null ">and targetid = #{targetid}</if>
            <if test="ID != null ">and id = #{ID}</if>
            <if test="revisitAfter != null ">and revisit_after = #{revisitAfter}</if>
            <if test="revisitBefore != null ">and revisit_before = #{revisitBefore}</if>
            <if test="mateNum != null ">and mate_num = #{mateNum}</if>
            <if test="mateNum != null and mateNum > 0">and mate_num = #{mateNum}</if>
            <if test="suitway != null ">and suitway = #{suitway}</if>
            <if test="targetname != null and targetname !='' ">and targetname = #{targetname}</if>
            <if test="version != null and version !='' ">and version = #{version}</if>
@@ -127,6 +130,7 @@
            <if test="assortid != null ">and assortid = #{assortid}</if>
            <if test="parameter != null  and parameter != ''">and parameter = #{parameter}</if>
            <if test="tag != null  and tag != ''">and tag = #{tag}</if>
            <if test="noVoiceNum != null and noVoiceNum > 0">and no_voice_num = #{noVoiceNum}</if>
        </where>
    </select>
@@ -185,6 +189,7 @@
            <if test="mateNum != null ">mate_num</if>
            <if test="revisitAfter != null ">revisit_after</if>
            <if test="revisitBefore != null ">revisit_before</if>
            <if test="noVoiceNum != null and noVoiceNum > 0 ">no_voice_num</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="templateName != null and templateName != ''">#{templateName},</if>
@@ -233,6 +238,7 @@
            <if test="mateNum != null ">#{mateNum}</if>
            <if test="revisitAfter != null ">#{revisitAfter}</if>
            <if test="revisitBefore != null ">#{revisitBefore}</if>
            <if test="noVoiceNum != null and noVoiceNum > 0">#{noVoiceNum}</if>
        </trim>
    </insert>
@@ -282,9 +288,10 @@
            <if test="tag != null">tag = #{tag},</if>
            <if test="suitway != null">suitway = #{suitway},</if>
            <if test="otherdata != null">otherdata = #{otherdata},</if>
            <if test="mateNum != null ">mate_num = #{mateNum}</if>
            <if test="revisitAfter != null ">revisit_after = #{revisitAfter}</if>
            <if test="revisitBefore != null ">revisit_before = #{revisitBefore}</if>
            <if test="mateNum != null ">mate_num = #{mateNum},</if>
            <if test="revisitAfter != null ">revisit_after = #{revisitAfter},</if>
            <if test="revisitBefore != null ">revisit_before = #{revisitBefore},</if>
            <if test="noVoiceNum != null and noVoiceNum > 0 ">no_voice_num = #{noVoiceNum}</if>
        </trim>
        where ID = #{ID}
    </update>
smartor/src/main/resources/mapper/smartor/IvrLibaTemplateScriptMapper.xml
@@ -39,6 +39,8 @@
        <result property="targettype" column="targettype"/>
        <result property="targetvalue" column="targettalue"/>
        <result property="questiontitle" column="questiontitle"/>
        <result property="nextQuestion" column="next_question"/>
        <result property="otherdata" column="otherdata"/>
    </resultMap>
    <sql id="selectIvrLibaTemplateScriptVo">
@@ -62,6 +64,8 @@
               targettype,
               targetvalue,
               questiontitle,
               next_question,
               otherdata,
               targetOptions, language, playWavOnly, isEnable, del_flag, update_by, update_time, create_by, create_time, isupload, upload_time, orgid, pid, guid
        from ivr_liba_template_script
    </sql>
@@ -85,6 +89,7 @@
            <if test="noClearlyText != null  and noClearlyText != ''">and noClearlyText = #{noClearlyText}</if>
            <if test="noClearlyVoice != null  and noClearlyVoice != ''">and noClearlyVoice = #{noClearlyVoice}</if>
            <if test="questiontitle != null  and questiontitle != ''">and questiontitle = #{questiontitle}</if>
            <if test="nextQuestion != null  and nextQuestion != ''">and next_question = #{nextQuestion}</if>
            <if test="categoryName != null  and categoryName != ''">and categoryName like concat('%', #{categoryName},
                '%')
            </if>
@@ -146,6 +151,8 @@
            <if test="targettype != null">targettype,</if>
            <if test="targetid != null">targetid,</if>
            <if test="questiontitle != null">questiontitle,</if>
            <if test="nextQuestion != null">next_question,</if>
            <if test="otherdata != null">otherdata,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="templateQuestionNum != null">#{templateQuestionNum},</if>
@@ -181,6 +188,8 @@
            <if test="targettype != null">#{targettype},</if>
            <if test="targetid != null">#{targetid},</if>
            <if test="questiontitle != null">#{questiontitle},</if>
            <if test="nextQuestion != null">#{nextQuestion},</if>
            <if test="otherdata != null">#{otherdata},</if>
        </trim>
    </insert>
@@ -220,6 +229,8 @@
            <if test="targettype != null">targettype = #{targettype},</if>
            <if test="targetid != null">targetid = #{targetid},</if>
            <if test="questiontitle != null">questiontitle = #{questiontitle},</if>
            <if test="nextQuestion != null">next_question = #{nextQuestion},</if>
            <if test="otherdata != null">otherdata = #{otherdata},</if>
        </trim>
        where ID = #{ID}
    </update>
smartor/src/main/resources/mapper/smartor/IvrLibaTemplateTargetoptionMapper.xml
@@ -34,6 +34,7 @@
        <result property="pid" column="pid"/>
        <result property="guid" column="guid"/>
        <result property="scriptid" column="scriptid"/>
        <result property="nextQuestion" column="next_question"/>
    </resultMap>
    <sql id="selectIvrLibaTemplateTargetoptionVo">
@@ -49,6 +50,8 @@
               targetregex2,
               nodynamiccruxs,
               dynamiccruxs,
               targetid,
               next_question,
               optiondesc, language, version, groupid, isabnormal, warnup, warndown, del_flag, update_by, update_time, create_by, create_time, isupload, upload_time, orgid, pid, guid
        from ivr_liba_template_targetoption
    </sql>
@@ -122,6 +125,7 @@
            <if test="orgid != null">orgid,</if>
            <if test="pid != null">pid,</if>
            <if test="guid != null">guid,</if>
            <if test="nextQuestion != null">next_question,</if>
            <if test="nodynamiccruxsJson != null ">nodynamiccruxs,</if>
            <if test="dynamiccruxsJson != null ">dynamiccruxs,</if>
        </trim>
@@ -152,6 +156,7 @@
            <if test="orgid != null">#{orgid},</if>
            <if test="pid != null">#{pid},</if>
            <if test="guid != null">#{guid},</if>
            <if test="nextQuestion != null">#{nextQuestion},</if>
            <if test="nodynamiccruxsJson != null ">#{nodynamiccruxsJson},</if>
            <if test="dynamiccruxsJson != null ">#{dynamiccruxsJson},</if>
        </trim>
@@ -163,7 +168,7 @@
            <if test="targetid != null">targetid = #{targetid},</if>
            <if test="scriptid != null">scriptid = #{scriptid},</if>
            <if test="targetname != null">targetname = #{targetname},</if>
            <if test="templateid != null">templateID = #{templateid},</if>
            <if test="templateID != null">templateID = #{templateID},</if>
            <if test="targettype != null and targettype != ''">targettype = #{targettype},</if>
            <if test="categoryName != null and categoryName != ''">categoryName = #{categoryName},</if>
            <if test="targetvalue != null">targetvalue = #{targetvalue},</if>
@@ -186,6 +191,7 @@
            <if test="orgid != null">orgid = #{orgid},</if>
            <if test="pid != null">pid = #{pid},</if>
            <if test="guid != null">guid = #{guid},</if>
            <if test="nextQuestion != null">next_question = #{nextQuestion},</if>
            <if test="nodynamiccruxsJson != null ">nodynamiccruxs = #{nodynamiccruxsJson},</if>
            <if test="dynamiccruxsJson != null ">dynamiccruxs = #{dynamiccruxsJson},</if>
        </trim>
smartor/src/main/resources/mapper/smartor/IvrTaskcallMapper.xml
@@ -55,6 +55,8 @@
        <result property="icdName" column="icd_name"/>
        <result property="medicalRecordNo" column="medical_record_no"/>
        <result property="preachcontent" column="preachcontent"/>
        <result property="sendType" column="send_type"/>
        <result property="sendTimeSlot" column="send_time_slot"/>
    </resultMap>
    <sql id="selectIvrTaskcallVo">
@@ -104,9 +106,11 @@
               guid,
               text_param,
               serviceform,
               badNo,
               icdName,
               medicalRecordNo,
               bad_no,
               icd_name,
               send_type,
               medical_record_no,
               send_time_slot,
               preachcontent
        from ivr_taskcall
    </sql>
@@ -153,13 +157,15 @@
            <if test="uploadTime != null ">and upload_time = #{uploadTime}</if>
            <if test="orgid != null  and orgid != ''">and orgid = #{orgid}</if>
            <if test="pid != null ">and pid = #{pid}</if>
            <if test="piserviceformd != null ">and serviceform = #{serviceform}</if>
            <if test="serviceform != null ">and serviceform = #{serviceform}</if>
            <if test="guid != null  and guid != ''">and guid = #{guid}</if>
            <if test="textParam != null  and textParam != ''">and text_param = #{textParam}</if>
            <if test="badNo != null">and bad_no = #{badNo}</if>
            <if test="icdName != null  and icdName != ''">and icd_name = #{icdName}</if>
            <if test="medicalRecordNo != null  and medicalRecordNo != ''">and medical_record_no = #{medicalRecordNo}</if>
            <if test="medicalRecordNo != null  and medicalRecordNo != ''">and medical_record_no = #{medicalRecordNo}
            </if>
            <if test="preachcontent != null  and preachcontent != ''">and preachcontent = #{preachcontent}</if>
            <if test="sendType != null  and sendType != ''">and send_type = #{sendType}</if>
        </where>
    </select>
@@ -168,10 +174,9 @@
        where id = #{id}
    </select>
    <insert id="insertIvrTaskcall" parameterType="com.smartor.domain.IvrTaskcall">
    <insert id="insertIvrTaskcall" parameterType="com.smartor.domain.IvrTaskcall"  useGeneratedKeys="true" keyProperty="id">
        insert into ivr_taskcall
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">id,</if>
            <if test="sendname != null">sendname,</if>
            <if test="phone != null">phone,</if>
            <if test="sex != null">sex,</if>
@@ -221,9 +226,9 @@
            <if test="icdName != null  and icdName != ''">icd_name,</if>
            <if test="medicalRecordNo != null  and medicalRecordNo != ''">medical_record_no,</if>
            <if test="preachcontent != null  and preachcontent != ''">preachcontent,</if>
            <if test="sendType != null  and sendType != ''">send_type,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="id != null">#{id},</if>
            <if test="sendname != null">#{sendname},</if>
            <if test="phone != null">#{phone},</if>
            <if test="sex != null">#{sex},</if>
@@ -273,6 +278,7 @@
            <if test="icdName != null  and icdName != ''">#{icdName},</if>
            <if test="medicalRecordNo != null  and medicalRecordNo != ''">#{medicalRecordNo},</if>
            <if test="preachcontent != null  and preachcontent != ''">#{preachcontent},</if>
            <if test="sendType != null  and sendType != ''">#{sendType},</if>
        </trim>
    </insert>
@@ -328,6 +334,7 @@
            <if test="icdName != null  and icdName != ''">icd_name = #{icdName},</if>
            <if test="medicalRecordNo != null  and medicalRecordNo != ''">medical_record_no = #{medicalRecordNo},</if>
            <if test="preachcontent != null  and preachcontent != ''">preachcontent = #{preachcontent},</if>
            <if test="sendType != null  and sendType != ''">send_type = #{sendType},</if>
        </trim>
        where id = #{id}
    </update>
@@ -340,4 +347,69 @@
        where id = #{id}
    </update>
    <select id="getDataByTime" resultMap="IvrTaskcallResult">
        select id,
               sendname,
               phone,
               sex,
               age,
               sfzh,
               addr,
               senderdetail,
               type,
               taskid,
               templateid,
               templatename,
               senddate,
               sendlimitabegin,
               sendlimitaend,
               sendlimitpbegin,
               sendlimitpend,
               sendlimitnbegin,
               sendlimitnend,
               sendstate,
               senduuid,
               result,
               finishtime,
               userid,
               username,
               outbounduuid,
               recordid,
               recallcount,
               exrecallcount,
               pulltime,
               bqsms,
               bhsms,
               deptcode,
               labelstatus,
               del_flag,
               update_by,
               update_time,
               create_by,
               create_time,
               isupload,
               upload_time,
               orgid,
               pid,
               guid,
               text_param,
               serviceform,
               bad_no,
               icd_name,
               send_type,
               medical_record_no,
               preachcontent,
               send_time_slot
        FROM ivr_taskcall,
             JSON_TABLE(send_time_slot, '$[*]' COLUMNS (
        begantime DATETIME PATH '$.begantime',
        endtime DATETIME PATH '$.endtime'
        )) AS jt
        WHERE jt.begantime > #{beganTime}
          AND jt.begantime &lt;= #{endTime}
          AND sendstate IS NULL
    </select>
</mapper>