liusheng
2025-02-14 b0da81d9276922b223583807093bd6420d9bf705
优化电话拨打功能
已修改6个文件
99 ■■■■■ 文件已修改
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-druid.yml 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java
@@ -190,8 +190,8 @@
    @PostMapping("/phoneCallBackYQ")
    public PhoneCallBackYQVO phoneCallBackYQ(@RequestBody PhoneCallReqYQVO phoneCallReqYQVO) {
        log.error("电话ASR通话回调(雨绮) ?{}", phoneCallReqYQVO);
        SysUser user = getLoginUser().getUser();
        phoneCallReqYQVO.setOrgid(user.getOrgid());
//        SysUser user = getLoginUser().getUser();
//        phoneCallReqYQVO.setOrgid(user.getOrgid());
        PhoneCallBackYQVO phoneCallBackYQVO = serviceSubtaskService.phoneCallBackYQ(phoneCallReqYQVO);
        return phoneCallBackYQVO;
    }
@@ -214,8 +214,8 @@
    @ApiOperation("患者问题结果记录(电话)")
    @PostMapping("/saveQuestionAnswerPhone")
    public AjaxResult saveQuestionAnswerPhone(@RequestBody ServiceSubTaskDetailReq serviceSubTaskDetailReq) {
        SysUser user = getLoginUser().getUser();
        serviceSubTaskDetailReq.setOrgid(user.getOrgid());
//        SysUser user = getLoginUser().getUser();
//        serviceSubTaskDetailReq.setOrgid(user.getOrgid());
        return toAjax(serviceSubtaskService.saveQuestionAnswerPhone(serviceSubTaskDetailReq));
    }
@@ -236,8 +236,8 @@
    public AjaxResult recordAccept(@RequestBody PhoneCallRecordVO phoneCallRecordVO) {
        log.error("通话记录回调(雨绮):{}", phoneCallRecordVO);
//        return toAjax(serviceSubtaskService.saveQuestionAnswerPhone(serviceSubTaskDetailReq));
        SysUser user = getLoginUser().getUser();
        phoneCallRecordVO.setOrgid(user.getOrgid());
//        SysUser user = getLoginUser().getUser();
//        phoneCallRecordVO.setOrgid(user.getOrgid());
        serviceSubtaskService.recordAccept(phoneCallRecordVO);
        return success();
    }
ruoyi-admin/src/main/resources/application-druid.yml
@@ -11,12 +11,12 @@
        #        username: root
        #        password: 123456
        #        公司
        # url: jdbc:mysql://192.168.2.9:3308/smartor?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        url: jdbc:mysql://192.168.2.9:3308/smartor?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        #        丽水
        #        url: jdbc:mysql://127.0.0.1:3308/smartor-lisui?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        #        username: smartor
        #        password: Smartor.2023
        #        driverClassName: com.mysql.cj.jdbc.Driver
        username: smartor
        password: Smartor.2023
        driverClassName: com.mysql.cj.jdbc.Driver
        # 新华
        # url: jdbc:mysql://192.168.191.181:3308/smartor?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        # username: smartor
@@ -24,10 +24,10 @@
        # driverClassName: com.mysql.cj.jdbc.Driver
        #        公司云
        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
        #        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:
@@ -151,12 +151,12 @@
qrpath: D:\qrcode
#公司内外链请求IP和端口号
#req_path: 8095
#localIP: 192.168.2.13
req_path: 8095
localIP: 192.168.2.13
#新华医院外链请求IP和端口号
req_path: 8093
localIP: https://wx.lihusmart.com
#req_path: 8093
#localIP: https://wx.lihusmart.com
#获取患者信息URL(华卓提供)
hosp_info_url: http://esb-core-rest.wowjoy.cn/esb/exchange
@@ -165,23 +165,23 @@
uploadSwitch: 1
##  指定asr回调的url路径(本地)
#ASRCallBackPath: http://192.168.2.13:8095/smartor/serviceSubtask/phoneCallBackYQ
ASRCallBackPath: http://192.168.2.13:8095/smartor/serviceSubtask/phoneCallBackYQ
##挂断IP(本地)
#hangup: http://192.168.2.13:8091/hangup
hangup: http://192.168.2.13:8091/hangup
##fs所使用的阿里的app_key(本地)
#app_key_yq: ZurNHpaQLq6P55YS
#  指定asr回调的url路径(新华)
ASRCallBackPath: http://192.168.101.135:8095/smartor/serviceSubtask/phoneCallBackYQ
#ASRCallBackPath: http://192.168.101.135:8095/smartor/serviceSubtask/phoneCallBackYQ
#挂断IP(新华)
hangup: http://192.16.4.220:8091/hangup
#hangup: http://192.16.4.220:8091/hangup
#fs所使用的阿里的app_key(新华)
app_key_yq: ZurNHpaQLq6P55YS
#本 地 短信请求地址(这个服务是我们自己写的)
#xhsmsPath: http://192.168.2.13:8092/sendSms
xhsmsPath: http://192.168.2.13:8092/sendSms
#新华短信请求地址(这个服务是我们自己写的)
xhsmsPath: http://192.16.4.220:8092/sendSms
#xhsmsPath: http://192.16.4.220:8092/sendSms
#帐号
xhsmsAccount: 911124
#接口密码
@@ -200,12 +200,12 @@
FTP_PASSWORD: xh@2023
#语音地址访问前缀(新华)
voicePathPrefix: http://192.168.191.181:8095/profile/upload/vadio/
#voicePathPrefix: http://192.168.191.181:8095/profile/upload/vadio/
#语音地址访问前缀(公司)
#voicePathPrefix: http://192.168.2.13:8095/profile/upload/vadio/
voicePathPrefix: http://192.168.2.13:8095/profile/upload/vadio/
#允许自动生成任务
createTaskServiceType: 2
#每天电话立即执行的上限
phoneUpEveryHour: 120
phoneUpEveryHour: 10
ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
@@ -8,10 +8,7 @@
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
/**
@@ -245,6 +242,19 @@
    }
    /**
     * 删除缓存LIST中的某个数据
     *
     * @param key           Redis键
     * @param valueToRemove 需要删除的值
     * @return Long 大于0表示删除了几个,等于0表示没有删除,小于0表示在执行删除操作时发生了错误
     */
    public Long removeElementFromList(String key, String valueToRemove) {
        ListOperations<String, String> listOps = redisTemplate.opsForList();
        Long remove = listOps.remove(key, 0, valueToRemove);
        return remove;
    }
    /**
     * 获得缓存的基本对象列表
     *
     * @param pattern 字符串前缀
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -343,8 +343,9 @@
                        }
                    }
                    //将要执行的放到缓存中
                    if (list.size() > 0) {
                    redisCache.setCacheList("cache-0", list);
                    }
                } else if (descByCode.equals("多媒体")) {
                    //多媒体
                } else if (descByCode.equals("纸质")) {
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -819,6 +819,9 @@
     */
    @Override
    public PhoneCallBackYQVO phoneCallBackYQ(PhoneCallReqYQVO phoneCallReqYQVO) {
        //先把该subId从cache_exist中剔除,只要有回调就剔除(目的是,尽快让cache-exist为空,去缓存下一批要打的电话;这里剔除不影响电话的正常业务)
        redisCache.removeElementFromList("cache-exist", phoneCallReqYQVO.getTaskid());
        //判断是否挂机
        String hangupState = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "- hangup");
        Object cacheObject1 = redisCache.getCacheObject(phoneCallReqYQVO.getTaskid() + "recordAccept-hungup");
@@ -833,6 +836,12 @@
                if (ObjectUtils.isNotEmpty(cacheObject) && String.valueOf(cacheObject).equals("1")) {
                    return new PhoneCallBackYQVO();
                }
                //如果发送状态为6,就说明已经打完了,也没有必要继续往下走了
                if (StringUtils.isNotEmpty(phoneCallReqYQVO.getTaskid())) {
                    ServiceSubtask serviceSubtask = serviceSubtaskMapper.selectServiceSubtaskById(Long.valueOf(phoneCallReqYQVO.getTaskid()));
                    if (serviceSubtask.getSendstate() == 6L) return new PhoneCallBackYQVO();
                }
                ServiceSubtask serviceSubtask2 = new ServiceSubtask();
                serviceSubtask2.setRemark("电话发送成功(患者挂断)");
                serviceSubtask2.setSenduuid(phoneCallReqYQVO.getUuid());
@@ -1429,9 +1438,13 @@
    @Override
    public List<PullTaskVO> taskPull() {
        //pullTaskVOList用于数据返回
        List<PullTaskVO> pullTaskVOList = null;
        List<PullTaskVO> pullTaskVOList = new ArrayList<>();
        List<String> cacheList = new ArrayList<>();
        ListOperations<String, String> listOps = redisTemplate.opsForList();
        //必须等ache-exist全部打完才能拉取下一批(主要是怕所有的数据都堆在电话的缓存里,在规定的时间打不完)
        long existSize = listOps.size("cache-exist");
        if (existSize > 0) return pullTaskVOList;
        long size = listOps.size("cache-0");
        log.error("---------打电话之前缓存中的数据量:{}", size);
        int count = 0;
@@ -1465,12 +1478,16 @@
                listOps.trim("cache-0" + i, count1, -1);
            }
        }
        //existList用来记录接下来需要执行的子任务ID
        List<String> existList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(pullTaskVOList)) {
            //给回调参数赋值
            for (PullTaskVO pullTaskVO : pullTaskVOList) {
                existList.add(pullTaskVO.getTaskid());
                pullTaskVO.setAsrcallback(ASRCallBackPath);
            }
        }
        if (existList.size() != 0) redisCache.setCacheList("cache-exist", existList);
        log.error("-----------实际拉取的电话数据量:{}", pullTaskVOList.size());
        return pullTaskVOList;
    }
@@ -1853,6 +1870,7 @@
            ServiceSubtask serviceSubtask = new ServiceSubtask();
            serviceSubtask.setRemark("电话接通成功,患者拒绝随访");
            serviceSubtask.setId(Long.valueOf(phoneCallRecordVO.getTaskid()));
            serviceSubtask.setSendstate(6L);
            serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
            int startIndex = phoneCallRecordVO.getRecord_path().indexOf("voice") + "voice".length() + 1;  // 加1是跳过/符号
            int endIndex = phoneCallRecordVO.getRecord_path().lastIndexOf("/");
@@ -2051,7 +2069,9 @@
        redisCache.setCacheObject(subTaskId + "recordAccept-hungup", "1", 10, TimeUnit.MINUTES);
        if (StringUtils.isNotEmpty(serviceSubtask.getRemark())) serviceSubtask.setRemark("电话发送拒接,短信补偿发送成功");
        else serviceSubtask.setRemark("短信补偿发送成功");
        serviceSubtask.setSendstate(3L);
        serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
    }
    //通过当前时间,拉取电话总数
smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
@@ -254,7 +254,7 @@
        </if>
        <if test="serviceType != null  and serviceType != ''and serviceType == '2'">order by endtime desc</if>
        <if test="serviceType != null  and serviceType != ''and serviceType == '3'">order by admindate desc</if>
        -- order by update_time desc,id desc
        <!-- order by update_time desc,id desc -->
    </select>
    <select id="selectServiceSubtaskById" parameterType="Long" resultMap="ServiceSubtaskResult">