陈昶聿
昨天 db2a00f5df9990e55ebbdf16cf8c68c3d64fe09d
Merge branch 'master' into master-任务组

# Conflicts:
# ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
已修改47个文件
已添加2个文件
1897 ■■■■ 文件已修改
.idea/encodings.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/pom.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/SmsController.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatArchiveController.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceTaskController.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-huizhou.yml 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/dx/MessageSend.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/common/DeepSeekApi.java 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrLibaTemplateScript.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrLibaTemplateScriptVO.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrTaskTemplateScript.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/IvrTaskTemplateScriptVO.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/PatArchive.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceSubtask.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceSubtaskDetailTrace.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceSubtaskExport.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceSubtaskRes.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/ServiceTaskScriptQues.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/SvyLibTemplateScript.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/SvyLibTemplateScriptVO.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/SvyTaskTemplate.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/SvyTaskTemplateScript.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/SvyTaskTemplateScriptVO.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/VO/DetailTraceDealVO.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/IPatMedInhospService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/IPatMedOperationService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/IPatMedOuthospService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/IServiceSubtaskService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/PatMedOperationServiceImpl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/PatMedOuthospServiceImpl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceExternalServiceImpl.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskAnswerServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java 512 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceTaskServiceImpl.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/IvrLibaTemplateScriptMapper.xml 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/IvrTaskTemplateScriptMapper.xml 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/PatArchiveMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailTraceMapper.xml 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/SvyLibTemplateScriptMapper.xml 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/SvyTaskTemplateMapper.xml 74 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/SvyTaskTemplateScriptMapper.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/encodings.xml
@@ -39,6 +39,7 @@
    <file url="file://$PROJECT_DIR$/ruoyi-system/src/main/java" charset="UTF-8" />
    <file url="file://$PROJECT_DIR$/ruoyi-system/src/main/resources" charset="UTF-8" />
    <file url="file://$PROJECT_DIR$/smartor/src/main/java" charset="UTF-8" />
    <file url="file://$PROJECT_DIR$/smartor/src/main/java/com/smartor/common/DeepSeekApi.java" charset="UTF-8" />
    <file url="file://$PROJECT_DIR$/smartor/src/main/java/com/smartor/domain/PatMedOuthospProvisional.java" charset="UTF-8" />
    <file url="file://$PROJECT_DIR$/smartor/src/main/java/com/smartor/domain/ServiceSubtaskPreachform.java" charset="UTF-8" />
    <file url="file://$PROJECT_DIR$/smartor/src/main/java/com/smartor/mapper/PatMedOuthospProvisionalMapper.java" charset="UTF-8" />
@@ -54,4 +55,4 @@
    <file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
    <file url="PROJECT" charset="GBK" />
  </component>
</project>
</project>
ruoyi-admin/pom.xml
@@ -55,6 +55,13 @@
            <version>9.2.1.jre8</version>
        </dependency>
        <!-- Kingbase8 JDBC驱动 -->
        <dependency>
            <groupId>cn.com.kingbase</groupId>
            <artifactId>kingbase8</artifactId>
            <version>8.6.0</version>
        </dependency>
        <!-- æ ¸å¿ƒæ¨¡å—-->
        <dependency>
            <groupId>com.ruoyi</groupId>
ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java
@@ -493,16 +493,18 @@
                        if (active.equals("sltd")) {
                            data = MessageSend.sendMsg(sendMagParam.getContent(), "6", sendMagParam.getPhone(), LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
                            if (StringUtils.isNotEmpty(data)) {
                                ObjectMapper mapper = new ObjectMapper();
                                JsonNode root = mapper.readTree(data);
                                String status = root.get("result").get(0).get("status").asText();
                                if (status.equals("00000")) {
                                    s = "true";
                                } else {
                                    setFailPreachForm(serviceSubtask, sendPreachform, "短信发送失败: " + data, "5");
                                    throw new BaseException("短信发送失败");
                                String[] pairs = data.split("&");
                                String resultVal = null;
                                for (String pair : pairs) {
                                    String[] kv = pair.split("=", 2);
                                    if ("result".equals(kv[0])) {
                                        resultVal = kv.length > 1 ? kv[1] : null;
                                        break;
                                    }
                                }
                                if ("0".equals(resultVal)) {
                                    s = "true";
                                }
                            } else {
                                setFailPreachForm(serviceSubtask, sendPreachform, "短信发送失败: " + data, "5");
                                throw new BaseException("短信发送失败");
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/SmsController.java
@@ -121,9 +121,10 @@
            serviceOutPath.setRadix(format);
            serviceOutPath.setCreateTime(new Date());
            serviceOutPath.setOrgid(vo.getOrgid());
            iServiceOutPathService.insertServiceOutPath(serviceOutPath);
            String url = ip + ":" + req_path + "/wt?p=" + format;
            content = "您好,邀请您填写出院调查表,请点击" + url + "填写。感谢您配合!";
            serviceOutPath.setUrl(url);
            iServiceOutPathService.insertServiceOutPath(serviceOutPath);
        }
        if (ObjectUtils.isNotEmpty(vo.getContent())) content = vo.getContent();
@@ -216,5 +217,36 @@
        return AjaxResult.success(sendMsg);
    }
    /**
     * @param
     * @return
     */
    @ApiOperation("生成外链")
    @PostMapping("/getUrl")
    public AjaxResult getUrl(@RequestBody smsVO vo) throws UnsupportedEncodingException {
        String content = "";
        if (StringUtils.isNotEmpty(vo.getTaskId()) && StringUtils.isNotEmpty(vo.getPatId()) && StringUtils.isNotEmpty(vo.getSubId())) {
            RSAPublicKeyExample rsaPublicKeyExample = new RSAPublicKeyExample();
            String taskId = rsaPublicKeyExample.encryptedData(vo.getTaskId().toString(), pub_key);
            String patid = rsaPublicKeyExample.encryptedData(vo.getPatId().toString(), pub_key);
            String subId = rsaPublicKeyExample.encryptedData(vo.getSubId().toString(), pub_key);
            Integer radix = iServiceOutPathService.selectAutoId();
            String format = String.format("%03X", radix);
            ServiceOutPath serviceOutPath = new ServiceOutPath();
            serviceOutPath.setParam1(taskId);
            serviceOutPath.setParam2(patid);
            serviceOutPath.setParam3(vo.getTaskName());
            serviceOutPath.setParam6(subId);
            serviceOutPath.setRadix(format);
            serviceOutPath.setCreateTime(new Date());
            serviceOutPath.setOrgid(vo.getOrgid());
            String url = ip + ":" + req_path + "/wt?p=" + format;
//            content = "您好,邀请您填写出院调查表,请点击" + url + "填写。感谢您配合!";
            content = url;
            serviceOutPath.setUrl(url);
            iServiceOutPathService.insertServiceOutPath(serviceOutPath);
        }
        return AjaxResult.success(content);
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatArchiveController.java
@@ -53,10 +53,14 @@
    //@PreAuthorize("@ss.hasPermi('smartor:patarchive:list')")
    @AddOrgId(field = "orgid", paramIndex = 0, campusField = "campusid")
    @PostMapping("list")
    public TableDataInfo list(@RequestBody PatArchive patArchive) {
        PageUtils.startPageByPost(patArchive.getPageNum(), patArchive.getPageSize());
    public Map<String, Object> list(@RequestBody PatArchive patArchive) {
        patArchive.setPageNum(PageUtils.getOffset(patArchive.getPageNum(), patArchive.getPageSize()));
        List<PatArchive> list = patArchiveService.selectPatArchiveList(patArchive);
        return getDataTable(list);
        patArchive.setPageNum(null);
        patArchive.setPageSize(null);
        List<PatArchive> patArchives = patArchiveService.selectPatArchiveList(patArchive);
        return getDataTable3(patArchives.size(), list);
    }
    /**
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java
@@ -48,6 +48,8 @@
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static com.ruoyi.common.utils.SecurityUtils.getLoginUser;
/**
 * å•一任务(随访)Controller
 *
@@ -88,6 +90,12 @@
    @Value("${spring.profiles.active}")
    private String active;
    @Value("${localIP}")
    private String localIP;
    @Value("${req_path}")
    private String req_path;
    @Value("${isAdmin}")
    private List<Long> isAdmin;
@@ -105,6 +113,7 @@
        LoginUser loginUser = getLoginUser();
        SysUser user = loginUser.getUser();
        serviceSubtaskVO.setOrgid(user.getOrgid());
        serviceSubtaskVO.setCampusid(user.getCampusid());
        ServiceSubtaskEntity serviceSubtaskEntity = null;
        if (serviceSubtaskVO != null) {
            serviceSubtaskEntity = DtoConversionUtils.sourceToTarget(serviceSubtaskVO, ServiceSubtaskEntity.class);
@@ -914,20 +923,39 @@
        return serviceSubtaskService.smsSubTask(subid);
    }
    /**
     * è·³è½¬ä¸­é—´é¡µ
     *
     * @param taskId
     * @return
     */
    @PostMapping(value = "/goSfRelay")
    public AjaxResult goSfRelay(@RequestParam("taskId") Long taskId, @RequestParam("deptcode") String deptcode, @RequestParam("leavehospitaldistrictcode") String leavehospitaldistrictcode) {
        String url = localIP + ":" + req_path + "/SfRelay?taskid=" + taskId;
        if(StringUtils.isNotEmpty(deptcode)){
            url = url + "&deptcode=" + deptcode;
        }
        if(StringUtils.isNotEmpty(leavehospitaldistrictcode)){
            url = url + "&leavehospitaldistrictcode=" + leavehospitaldistrictcode;
        }
        return AjaxResult.success(url);
    }
    /**
     * æ‰«ç ç”Ÿæˆå­ä»»åŠ¡
     *
     * @param serviceTask
     * @return
     */
    @PostMapping(value = "/scanGenerateSubtask")
    public AjaxResult scanGenerateSubtask(@RequestBody ServiceTask serviceTask) {
        return AjaxResult.success(serviceSubtaskService.scanGenerateSubtask(serviceTask));
    }
    @PostMapping("/test")
    public void test() {
        ryTask.dealOutHospInfo();
    }
    @PostMapping("/compensateTasktest")
    public void compensateTasktest(@RequestParam("subId") Long subId) {
        ryTask.compensateTaskTest(subId);
    }
    @PostMapping("/longTaskSendtest")
    public void longTaskSendtest(@RequestParam("subId") Long subId) {
        ryTask.longTaskSendTest(subId);
    }
    @PostMapping("/syncMedInhospForShiyi")
@@ -945,4 +973,6 @@
        int result = ryTask.qwenLLMTest(questionText, voiceText, value, regexText);
        return result;
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceTaskController.java
@@ -219,18 +219,21 @@
    public AjaxResult getScriptInfoByCondition(@RequestBody ServiceTaskScriptQues serviceTaskScriptQues) {
        Long tid = null;
        Long pid = null;
        Long sid = null;
        log.info("getScriptInfoByCondition入参为:{}", serviceTaskScriptQues);
        try {
            tid = Long.valueOf(rsaPublicKeyExample.decryptedData(serviceTaskScriptQues.getParam1(), pri_key));
            if (StringUtils.isNotEmpty(serviceTaskScriptQues.getParam2()))
                pid = Long.valueOf(rsaPublicKeyExample.decryptedData(serviceTaskScriptQues.getParam2(), pri_key));
            if (StringUtils.isNotEmpty(serviceTaskScriptQues.getParam6()))
                sid = Long.valueOf(rsaPublicKeyExample.decryptedData(serviceTaskScriptQues.getParam6(), pri_key));
        } catch (Exception e) {
            log.error("getScriptInfoByCondition报错了:{}", e.getMessage());
        }
        log.info("tid和pid的值为:{},{}", tid, pid);
        if (StringUtils.isEmpty(serviceTaskScriptQues.getPatfrom())) serviceTaskScriptQues.setPatfrom("0");
        return success(serviceTaskService.getScriptInfoByCondition(tid, pid, true, serviceTaskScriptQues.getPatfrom(), null));
        return success(serviceTaskService.getScriptInfoByCondition(tid, pid, true, serviceTaskScriptQues.getPatfrom(), sid));
    }
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
@@ -137,7 +137,7 @@
            return buildRedirect(path + "/login");
        }
        String redirectUrl = path + "/loginSSO?token=" + loginToken + "&orgid=" + orgid + "&orgname=null&ZuHuID=null&deptCode=null";
        String redirectUrl = path + "/loginSSO?token=" + loginToken + "&orgid=" + orgid + "&campusid=" + campusid + "&orgname=null&ZuHuID=null&deptCode=null";
        log.info("【SSO登录】重定向地址:{}", redirectUrl);
        return buildRedirect(redirectUrl);
    }
ruoyi-admin/src/main/resources/application-huizhou.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,249 @@
# æ•°æ®æºé…ç½®
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    #    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:kingbase8://10.100.1.23:54321/smartor-huizhou?currentSchema=smartor,sys_catalog&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&connectTimeout=60000&socketTimeout=120000
        username: smartor
        password: smartor.2025
        driverClassName: com.kingbase8.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
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      #      validationQuery: SELECT 1 FROM DUAL
      validationQuery: SELECT 1
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: false
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: lihu
        login-password: Lihu@1363419#$
      filter:
        stat:
          enabled: false
          # æ…¢SQL记录
          log-slow-sql: false
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # redis é…ç½®
  redis:
    host: 127.0.0.1
    port: 6379
    # æ•°æ®åº“索引
    database: 0
    # å¯†ç 
    password: Smartor
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 30s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: false
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# PageHelper分页插件
#pagehelper:
#  helperDialect: mysql
#  supportMethodsArguments: true
##  params: countSql;pageSizeZero=true
magic-api:
  web: /magic/web
  resource:
    type: database   # é…ç½®å­˜å‚¨åœ¨æ•°æ®åº“中
    tableName: magic_config  # æ•°æ®åº“中的表名
    prefix: /api
    readonly: false
  sql-column-case: camel
  show-sql: true #配置打印SQL
  page-config:
    size: size
    page: page
    default-page: 1
    default-size: 10
#钉钉的密钥
dingAppid: dingn8iip5ubj7clrrsv
dingAppSecret: qlEK8D3oOVwGPOTiBQIBYTqQVlAfy9S_qQizEQFjJdSScwemWFryg4gbneu-NqWD
# websocket超时时间
server:
websocket:
timeout=60000:
accessKeyId: LTAI5tPfc1VJzz7VuhzcBwug
accessKeySecret: gG1srKxPFDBNWe2oHfqmK1qsSQkf1e
signName: æ­å·žåˆ©æ¹–科技
#智能呼叫(上海)
phoneIP: http://124.220.50.51
phonePort: 8001
#杭州
hzphoneIP: http://121.43.112.160
hzphonePort: 8088
#电话线路(1 ä¸Šæµ·ï¼Œ2 æ­å·žï¼‰
phonePath: 2
#自己的电话号码
phoneMySelf: 83234089
##授权 id(杭州)
#app_id: hzgs
##授权 key(已加密过的 key)(杭州)
#app_key: 605453540c4a0a692fe07e1cae1162f3
#授权 id(杭州)
app_id: hz_ali
#授权 key(已加密过的 key)(杭州)
app_key: a2f3b5799d635216aa280362fafd8c35
pub_key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALQzqW1EIXBKGMu+2oEYSB5gM7Ox/ihyYTeeoE0yPX1qtt4++5yNOeTBVd6EEM4iKzVEzWj6REIWVwaSNPn/SvUCAwEAAQ==
#这个是后端的私钥,用不到
pri_key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAtDOpbUQhcEoYy77agRhIHmAzs7H+KHJhN56gTTI9fWq23j77nI055MFV3oQQziIrNUTNaPpEQhZXBpI0+f9K9QIDAQABAkB3n0fcWfrcoMN/FU3VnrnZOEF6CzFNxkgU9P8y36QECWKZ9JhYQkNpKrMC9oXlN3VSaRigV7B+L/I/a0Rs1W+tAiEA4jx7xcXJ4y4BNwAmVHt6NNiEkzIwWnwC/0qsEu8NsOsCIQDL6MMn1D2uznC6OuOWpxDCkBh1JL1NzZTZeH2G+hj7nwIgKGAC9tjFnvWm4dn0/T7MIIJDpsFeP8fCAS2iZ/6hwuECIAS/eLvWr1EAsZNEh8QcQ8GkBU3E+ztyjAK8UX/xFt/VAiBf79/1tDErX4/DChecM8w3c3DhbBcjuE3fHZn7p6/UKg==
#前端私钥(用不到了)
#pri_key: MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEApHTIe/StslZAT5Jzv8XClbrqox32pfaTrP5IOCRJ3FaH/UZsGgA/tsNBBEXq9eagqwPbJrjYfpdEtINcChrK4wIDAQABAkEAilDujdKshGGmlUZHs/NQRT6AOdDpsYxBiC4V76IVvQpw0IW6c4HGEvH4T+xRufika7/48L0eu0f06H+YtL5lgQIhANUd0a6oSsVxWifAjtKwMZcXD3OaIxQIQSCN4NT4VFY3AiEAxYxYrIhkIyg+UVw3WOSvBpXKxM4/WL9HRzkxDLvp2rUCIQCK23P8tgCJ5xJT5l3onw6goFDcBKkoazxsBqVgfjENPwIgWbuTd+OIYPPhwsE5ntZZrosSDO2GlsBkFzUiU59z7VUCIA0LL+9IFb+FWCl3DGTwIQ9SZYbv61T83LKjebUcSOfe
#二维码路径
qrpath: D:\qrcode
#公司内外链请求IP和端口号
#req_path: 8095
#localIP: 192.168.2.13
#新华医院外链请求IP和端口号
req_path: 8093
#localIP: https://wx.lihusmart.com
#丽水外链请求IP和端口号
localIP: https://lishuisf.health-y.cn
#获取患者信息URL(华卓提供)
hosp_info_url: http://esb-core-rest.wowjoy.cn/esb/exchange
# 0代表走默认的上传    1 ä»£ç èµ°æ–°åŽåŒ»é™¢çš„上传
uploadSwitch: 1
##  æŒ‡å®šasr回调的url路径(本地)
#ASRCallBackPath: http://192.168.2.13:8095/smartor/serviceSubtask/phoneCallBackYQ
##挂断IP(本地)
#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
#挂断IP(新华)
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.16.4.220:8092/sendSms
#帐号
xhsmsAccount: 911124
#接口密码
xhsmsPwd: zW5eXe
#虚拟接入码
xhsmsjrm: 1069055
##本地FTP连接
#FTP_SERVER: "192.168.2.13"
#FTP_USERNAME: voice
#FTP_PASSWORD: xh@2023
#新华FTP连接
FTP_SERVER: "192.16.4.220"
FTP_USERNAME: voice
FTP_PASSWORD: xh@2023
#语音地址访问前缀(新华)
voicePathPrefix: http://192.168.191.181:8095/profile/upload/vadio/
#语音地址访问前缀(公司)
#voicePathPrefix: http://192.168.2.13:8095/profile/upload/vadio/
#第个小时电话拨打的上限
phoneUpEveryHour: 12
#电话每天结束时间
phoneEndHour: 20
#新员工默认密码
defaultPwd: 123456
#是否需要根据疾病建立出院患者随访
createIcd10Visit: false
#admin管理员userId
isAdmin: 1,2,3,4,5,6,7,8,9,10,11,12,13
#处理投诉建议的部门编码
dealDeptCode:
#是否加密  0不加   1加密
isEncryp: 0
#文件上传地址
fileUpload:
profile:
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
ruoyi-common/src/main/java/com/ruoyi/common/dx/MessageSend.java
@@ -1,6 +1,5 @@
package com.ruoyi.common.dx;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.uuid.UUID;
import lombok.extern.slf4j.Slf4j;
@@ -15,17 +14,33 @@
     * //     * @param sOrderNo        æ‚£è€…唯一号码
     * //     * @param sMessageContent çŸ­ä¿¡å†…容
     *
     * @param sMessageType  çŸ­ä¿¡ç±»åž‹   1=验证码、2=通知、3=广告
     * @param sMessageType  çŸ­ä¿¡ç±»åž‹   1=验证码、2=通知、3=广告 6=内容有链接和电话,7=钉钉消息
     * @param sUserNumber   æ‰‹æœºå·ç 
     * @param sScheduleTime é¢„约发送时间
     * @return
     */
    public static String sendMsg(String sMessageContent, String sMessageType, String sUserNumber, String sScheduleTime) {
        log.info("--sMessageContent的值为:{}   ,--sMessageType的值为:{},   --sUserNumber的值为:{},   --sScheduleTime的值为:{}", sMessageContent, sMessageType, sUserNumber, sScheduleTime);
        log.info("--sMessageContent çš„值为:{}   ,--sMessageType çš„值为:{},   --sUserNumber çš„值为:{},   --sScheduleTime çš„值为:{}", sMessageContent, sMessageType, sUserNumber, sScheduleTime);
        com.ruoyi.common.dx.SmsService service = new SmsService();
        SmsServiceSoap soap = service.getSmsServiceSoap();
        String result = soap.i5GSend("202508291634227086", "T202508291635259440", UUID.randomUUID().toString(), sMessageContent, sMessageType, sUserNumber, sScheduleTime);
        log.info("----短信返回的数据为:{},    ----sMessageContent的值为:{},", result, sMessageContent);
        String result = null;
        try {
            if ("6".equals(sMessageType)) {
                result = soap.i5GSend("202508291634227086", "T202508291635259440", UUID.randomUUID().toString(), sMessageContent, sMessageType, sUserNumber, sScheduleTime);
                log.info("----短信返回的数据为:{},    ----sMessageContent çš„值为:{}", UUID.randomUUID().toString());
            } else if ("7".equals(sMessageType)) {
                result = soap.i5GSend("202508291634227086", "T202607211306131891", UUID.randomUUID().toString(), sMessageContent, sMessageType, sUserNumber, sScheduleTime);
                log.info("----钉钉返回的原始数据为:{}", result);
            } else {
                log.warn("不支持的短信类型:{}", sMessageType);
            }
        } catch (Exception e) {
            log.error("完整错误信息:{}", e.getCause().getMessage());
        }
        return result;
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -108,7 +108,7 @@
                // è¿‡æ»¤è¯·æ±‚
                .authorizeRequests()
                // å¯¹äºŽç™»å½•login æ³¨å†Œregister éªŒè¯ç captchaImage å…è®¸åŒ¿åè®¿é—®
                .antMatchers("/login","/test/**", "/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/serviceSubtask/phoneCallBack", "/smartor/serviceSubtask/taskPull", "/smartor/serviceSubtask/phoneCallBackYQ", "/smartor/robot/callstatus", "/smartor/robot/aidialog", "/smartor/robot/cdrinfo", "/getToken", "/smartor/subtaskAnswer/getQuestionCache", "/smartor/subtaskAnswer/saveQuestionCache", "/smartor/servicetask/getScriptInfoByCondition", "/smartor/subtaskAnswer/saveQuestionAnswer", "/smartor/import/download", "/smartor/serviceSubtask/recordAccept", "/smartor/outPath/getInfoByParam", "/smartor/serviceExternal/addDeptInfo", "/smartor/serviceExternal/**", "/sso/**","/smartor/sltdHealthcareRecord/**","/smartor/servicetask/getScriptByCondition","/smartor/subtaskAnswer/saveMYDQuestionAnswer").permitAll()
                .antMatchers("/login","/test/**", "/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/serviceSubtask/phoneCallBack", "/smartor/serviceSubtask/taskPull", "/smartor/serviceSubtask/phoneCallBackYQ", "/smartor/robot/callstatus", "/smartor/robot/aidialog", "/smartor/robot/cdrinfo", "/getToken", "/smartor/subtaskAnswer/getQuestionCache", "/smartor/subtaskAnswer/saveQuestionCache", "/smartor/servicetask/getScriptInfoByCondition", "/smartor/subtaskAnswer/saveQuestionAnswer", "/smartor/import/download", "/smartor/serviceSubtask/recordAccept", "/smartor/outPath/getInfoByParam", "/smartor/serviceExternal/addDeptInfo", "/smartor/serviceExternal/**", "/sso/**","/smartor/sltdHealthcareRecord/**","/smartor/servicetask/getScriptByCondition","/smartor/subtaskAnswer/saveMYDQuestionAnswer","smartor/serviceSubtask/goSfRelay","/smartor/serviceSubtask/scanGenerateSubtask").permitAll()
                // é™æ€èµ„源,可匿名访问
//                .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**","/getDept/*","/SSOLogin/**").permitAll().antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
                .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**","/getDept/*","/SSOLogin/**","/system/dict/data/typeout/*").permitAll().antMatchers( "/druid/**").permitAll()
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -25,6 +25,7 @@
import com.smartor.common.MtSubmitSmUtil;
import com.smartor.common.QwenLLMUtil;
import com.smartor.domain.*;
import com.smartor.domain.VO.ServiceSubtaskDetailTraceVO;
import com.smartor.domain.entity.ServiceSubtaskEntity;
import com.smartor.mapper.*;
import com.smartor.service.*;
@@ -146,6 +147,9 @@
    ISysDeptService sysDeptService;
    @Autowired
    IServiceSubtaskDetailTraceService serviceSubtaskDetailTraceService;
    @Autowired
    IPatMedOuthospService patMedOuthospService;
    @Autowired
@@ -232,6 +236,38 @@
        serviceThirdData.setCreateTime(new Date());
        iServiceThirdDataService.queryList(serviceThirdData);
    }
    /**
     * å®šæ—¶å‘送SLTD满意度异常信息
     */
    public void sendSLTDMYDExceptInfo() {
        //1.获取发送人工号
        ServiceSubtaskDetailTraceVO subtaskDetailTraceVO = new ServiceSubtaskDetailTraceVO();
        subtaskDetailTraceVO.setHandleFlag("0");
        List<ServiceSubtaskDetailTrace> serviceSubtaskDetailTraces = serviceSubtaskDetailTraceService.selectServiceSubtaskDetailTtraceList(subtaskDetailTraceVO);
        // æŠŠ dutyDeptPersonCode æ•´ç†åˆ° list ä¸­ï¼ˆå¦‚果多个人用逗号分割,则展开并去重)
        List<String> dutyDeptPersonCodeList = serviceSubtaskDetailTraces.stream().map(ServiceSubtaskDetailTrace::getDutyDeptPersonCode).filter(StringUtils::isNotBlank).flatMap(code -> Arrays.stream(code.split(","))).map(String::trim).filter(StringUtils::isNotBlank).distinct()  // åŽ»é‡
                .collect(Collectors.toList());
        // èŽ·å–â€œçœç«‹åŒå¾·æ»¡æ„åº¦å¼‚å¸¸å†…å®¹æé†’"
        SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique("sltd.myd.send.except.contont");
        String exceptContent = sysConfig.getConfigValue();
        // èŽ·å–â€œçœç«‹åŒå¾·æ»¡æ„åº¦å¼‚å¸¸å†…å®¹æé†’æµ‹è¯•äººå·¥å·â€
        String testPerson = sysConfigMapper.checkConfigKeyUnique("sltd.myd.send.test.person").getConfigValue();
        if (StringUtils.isNotBlank(testPerson)) {
            String[] split = testPerson.split(",");
            if (CollectionUtils.isEmpty(dutyDeptPersonCodeList)) dutyDeptPersonCodeList = Arrays.asList(split);
            else dutyDeptPersonCodeList.addAll(Arrays.asList(split));
        }
        if (CollectionUtils.isNotEmpty(dutyDeptPersonCodeList)) {
            for (String dutyDeptPersonCode : dutyDeptPersonCodeList) {
                log.info("【sendSLTDMYDExceptInfo】发送人工号:{}", dutyDeptPersonCode);
                String data = MessageSend.sendMsg(exceptContent, "7", dutyDeptPersonCode, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
            }
        }
    }
    /**
     * å®šæ—¶å¤„理外链的数据
@@ -603,7 +639,7 @@
            serviceSLTDInhospReqVO.setCurrent(outpPage);
            serviceSLTDInhospReqVO.setSize(OUTP_PAGE_SIZE);
            log.info("【dealHisData】省立同德“药品数据”采集第{}页数据", outpPage);
           Boolean b = serviceSLTDHealthcareRecordService.queryMedicationItemList(serviceSLTDInhospReqVO);
            Boolean b = serviceSLTDHealthcareRecordService.queryMedicationItemList(serviceSLTDInhospReqVO);
            log.info("【dealHisData】省立同德“药品数据”采集结果:{}", b);
            outpPage++;
        }
@@ -762,91 +798,16 @@
     * å¤„理补偿任务
     */
    public void compensateTask() {
        //获取到sendstate=3 å¹¶ä¸” visit_time为小于等于今天的subtask
        //获取到sendstate=3、1 å¹¶ä¸” visit_time为小于等于今天的subtask
        List<Long> list = Arrays.asList(3L, 1L);
        ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity();
        serviceSubtaskVO.setSendstate(3L);
        serviceSubtaskVO.setVisitTime(new Date());
        List<ServiceSubtask> serviceSubtaskList = serviceSubtaskMapper.getCompensateServiceSubtaskList(serviceSubtaskVO);
        for (ServiceSubtask serviceSubtask : serviceSubtaskList) {
            //根据当前的执行方式,获取下一种执行方式
            ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
            serviceSubtaskPreachform.setTaskid(serviceSubtask.getTaskid());
            serviceSubtaskPreachform.setSubid(serviceSubtask.getId());
            serviceSubtaskPreachform.setOrgid(serviceSubtask.getOrgid());
            List<ServiceSubtaskPreachform> serviceSubtaskPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
            //获取当前执行方式的序号
            Optional<Long> currentSort = serviceSubtaskPreachforms.stream().filter(item -> serviceSubtask.getCurrentPreachform().equals(item.getPreachform())).map(ServiceSubtaskPreachform::getSort).findFirst();
            Optional<Long> id = serviceSubtaskPreachforms.stream().filter(item -> serviceSubtask.getCurrentPreachform().equals(item.getPreachform())).map(ServiceSubtaskPreachform::getId).findFirst();
            if (currentSort.isPresent()) {
                //1先检查一下,是不是有执行状态是完成的(怕之前已经有完的了,没有将servuce_subtask的状态改成功,这里再检查一下)
                boolean finishState = serviceSubtaskPreachforms.stream().allMatch(item -> item.getSendstate().equals("9"));
                if (finishState) {
                    serviceSubtask.setSendstate(6L);
                    serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                    continue;
                }
                //2判断一下,当前的sort是不是等于需要执行的总个数,如果等于的话,说明是最后一个,直接将servuce_subtask的状态改成5,执行失败就行了
                Long cs = currentSort.get();
                if (cs.equals(serviceSubtaskPreachforms.size())) {
                    serviceSubtask.setSendstate(7L);
                    serviceSubtask.setRemark("处理补偿任务,当前处理最后补偿,全部执行失败(超时)");
                    serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                    //修改发送方式的状态为失败
                    serviceSubtaskPreachform.setSendstate("5");
                    serviceSubtaskPreachform.setId(id.get());
                    serviceSubtaskPreachformMapper.updateServiceSubtaskPreachform(serviceSubtaskPreachform);
                    continue;
                }
                //3.不是最后一个,获取到下一个执行方式(因为都是在今天执行,那就直接发出去就完了)
                sfHandlle(serviceSubtask);
            }
        }
    }
    /**
     * é•¿æœŸä»»åŠ¡å‘é€
     */
    public void longTaskSendTest(Long subId) {
        //获取任务信息
        ServiceTask st = new ServiceTask();
        st.setDelFlag("0");
        st.setLongTask(1);
        List<ServiceTask> serviceTasks = serviceTaskMapper.selectServiceTaskList(st);
        log.info("【longTaskSend】获取到{}个长期任务", serviceTasks.size());
        for (ServiceTask serviceTask : serviceTasks) {
            CommonTaskcallMQ commonTaskcallMQ = new CommonTaskcallMQ();
            commonTaskcallMQ.setTaskid(serviceTask.getTaskid());
            commonTaskcallMQ.setPreachform(serviceTask.getPreachform());
            commonTaskcallMQ.setSendType("2");
            //通过任务ID拿到患者信息,并且随访时间得是今天之前的
            ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity();
            serviceSubtaskVO.setTaskid(commonTaskcallMQ.getTaskid());
            serviceSubtaskVO.setSendstate(2L);
            serviceSubtaskVO.setIsVisitAgain(1);
            serviceSubtaskVO.setSubId(subId);
        List<ServiceSubtask> serviceSubtaskList = new ArrayList<>();
        for (Long sendstate : list) {
            serviceSubtaskVO.setSendstate(sendstate);
            serviceSubtaskVO.setVisitTime(new Date());
            List<ServiceSubtask> selectServiceSubtaskList = serviceSubtaskMapper.queryServiceSubtaskList(serviceSubtaskVO);
            for (ServiceSubtask serviceSubtask : selectServiceSubtaskList) {
                sfHandlle(serviceSubtask);
            }
            List<ServiceSubtask> compensateServiceSubtaskList = serviceSubtaskMapper.getCompensateServiceSubtaskList(serviceSubtaskVO);
            serviceSubtaskList.addAll(compensateServiceSubtaskList);
        }
    }
    /**
     * å¤„理补偿任务
     */
    public void compensateTaskTest(Long subId) {
        //获取到sendstate=3 å¹¶ä¸” visit_time为小于等于今天的subtask
        ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity();
        serviceSubtaskVO.setSendstate(3L);
        serviceSubtaskVO.setSubId(subId);
        serviceSubtaskVO.setVisitTime(new Date());
        List<ServiceSubtask> serviceSubtaskList = serviceSubtaskMapper.getCompensateServiceSubtaskList(serviceSubtaskVO);
        for (ServiceSubtask serviceSubtask : serviceSubtaskList) {
            //根据当前的执行方式,获取下一种执行方式
            ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
@@ -1146,10 +1107,18 @@
                            //省立同德的短信发送方式
                            String data = MessageSend.sendMsg(sendMagParam.getContent(), "6", sendMagParam.getPhone(), LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
                            if (StringUtils.isNotEmpty(data)) {
                                ObjectMapper mapper = new ObjectMapper();
                                JsonNode root = mapper.readTree(data);
                                String status = root.get("result").get(0).get("status").asText();
                                if (status.equals("00000")) {
                                // è§£æž result=0&description=成功&faillist= æ ¼å¼ï¼ˆresult=0成功,1失败)
                                log.info("【sfHandlle】省立同德短信发送返回:{}", data);
                                String[] pairs = data.split("&");
                                String resultVal = null;
                                for (String pair : pairs) {
                                    String[] kv = pair.split("=", 2);
                                    if ("result".equals(kv[0])) {
                                        resultVal = kv.length > 1 ? kv[1] : null;
                                        break;
                                    }
                                }
                                if ("0".equals(resultVal)) {
                                    isSuccess = "true";
                                }
                            }
@@ -1234,11 +1203,7 @@
                    String patid = rsaPublicKeyExample.encryptedData(serviceSubtask.getPatid().toString(), pub_key);
                    String subId = rsaPublicKeyExample.encryptedData(serviceSubtask.getId().toString(), pub_key);
                    String url = null;
                    url = localIP + ":" + req_path + "/outsideChainwt?param1=" + taskId +
                            "&param2=" +  patid +
                            "&param3=" + URLEncoder.encode(ivrTask1.getTaskName(), StandardCharsets.UTF_8.toString()) +
                            "&param5=false" +
                            "$param6=" + subId;
                    url = localIP + ":" + req_path + "/outsideChainwt?param1=" + taskId + "&param2=" + patid + "&param3=" + URLEncoder.encode(ivrTask1.getTaskName(), StandardCharsets.UTF_8.toString()) + "&param5=false" + "$param6=" + subId;
                    ServiceOutPath serviceOutPath = new ServiceOutPath();
                    serviceOutPath.setParam1(taskId);
smartor/pom.xml
@@ -145,6 +145,12 @@
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- Kingbase8 JDBC驱动 -->
        <dependency>
            <groupId>cn.com.kingbase</groupId>
            <artifactId>kingbase8</artifactId>
            <version>8.6.0</version>
        </dependency>
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-system</artifactId>
smartor/src/main/java/com/smartor/common/DeepSeekApi.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,178 @@
package com.smartor.common;
;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.util.*;
@Slf4j
public class DeepSeekApi {
    // æ›¿æ¢ä¸ºä½ è‡ªå·±çš„key
    private static final String API_KEY = "sk-4e489637e105411596be6c72e2dacdbd";
    private static final String API_URL = "https://api.deepseek.com/v1/chat/completions";
    public static void main(String[] args) {
        String questionText = "您好,请问您是患者本人还是家属?\n";
        String voiceText = "我自己";
//        List<String> options = new ArrayList<>(Arrays.asList("本人","亲属","其他"));
        String optionText = "亲属";
        Integer resp = matchQuestionAnswer(questionText, voiceText, optionText);
        System.out.println("DeepSeek返回结果:\n" + resp);
    }
    public static String chatCompletion(String systemPrompt, String userPrompt) {
        OkHttpClient client = new OkHttpClient();
        // 1. ç»„装消息体
        List<Map<String, String>> messages = new ArrayList<>();
        // ç³»ç»Ÿè§’色(可选,用于设定AI身份)
        Map<String, String> sysMsg = new HashMap<>();
        sysMsg.put("role", "system");
        sysMsg.put("content", systemPrompt);
        messages.add(sysMsg);
        // ç”¨æˆ·æé—®
        Map<String, String> userMsg = new HashMap<>();
        userMsg.put("role", "user");
        userMsg.put("content", userPrompt);
        messages.add(userMsg);
        // 2. è¯·æ±‚参数
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", "deepseek-chat");
        requestBody.put("messages", messages);
        requestBody.put("temperature", 0.7); // éšæœºæ€§0~1,越低越严谨
        requestBody.put("max_tokens", 1024);
        // 3. æž„建请求
        String jsonBody = JSON.toJSONString(requestBody);
        RequestBody body = RequestBody.create(MediaType.parse("application/json"), jsonBody);
        Request request = new Request.Builder()
                .url(API_URL)
                .header("Authorization", "Bearer " + API_KEY)
                .header("Content-Type", "application/json")
                .post(body)
                .build();
        // 4. å‘送请求
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                return "请求失败,状态码:" + response.code() + ",错误信息:" + response.body().string();
            }
            String resJson = response.body().string();
            JSONObject jsonObj = JSON.parseObject(resJson);
            // æå–AI回答内容
            return jsonObj.getJSONArray("choices")
                    .getJSONObject(0)
                    .getJSONObject("message")
                    .getString("content");
        } catch (IOException e) {
            e.printStackTrace();
            return "接口调用异常:" + e.getMessage();
        }
    }
    /**
     * åˆ¤æ–­è¯­éŸ³æ–‡æœ¬æœ€æŽ¥è¿‘哪个选项,返回选项在列表中的下标。
     *
     * @param voiceText è¯­éŸ³è¯†åˆ«å¾—到的文本
     * @param options   å€™é€‰é€‰é¡¹åˆ—表
     * @return å‘½ä¸­é€‰é¡¹çš„下标(从 0 å¼€å§‹ï¼‰ï¼›æ— æ³•匹配任一选项时返回 {@code -1}
     */
    public static int matchOptionIndex(String questionText, String voiceText, List<String> options) {
        if (StringUtils.isBlank(voiceText) || options == null || options.isEmpty()) {
            return -1;
        }
        // åªæœ‰ä¸€ä¸ªé€‰é¡¹æ—¶æ— éœ€è°ƒç”¨æ¨¡åž‹
        if (options.size() == 1) {
            return 0;
        }
        StringBuilder optionText = new StringBuilder();
        for (int i = 0; i < options.size(); i++) {
            optionText.append(i + 1).append(". ").append(options.get(i)).append('\n');
        }
        String systemPrompt = "\"你是一个专业的语音识别文本语义匹配助手。你的任务是判断用户的语音文本在语义上最符合的选项。用户会给出一段语音识别文本和若干个带编号的选项,"
                + "请判断这段文本在语义上最接近哪一个选项。只允许从给定选项中选择,"
                + "不要做任何解释。直接输出最匹配选项的编号数字;若没有任何选项与文本相关,则输出 0。";
        String userPrompt = "请根据以下信息进行语义匹配判断:\n" +
                "- é—®é¢˜æ–‡æœ¬ï¼š" + questionText + "\n\n"
                + "- è¯­éŸ³è¯†åˆ«æ–‡æœ¬ï¼š" + voiceText + "\n\n"
                + "- é€‰é¡¹ï¼š\n" + optionText
                + "\n请只输出一个数字(最匹配选项的编号,没有匹配则输出 0)。";
        String content = chatCompletion(systemPrompt, userPrompt);
        if (StringUtils.isBlank(content)) {
            return -1;
        }
        Integer number = extractFirstNumber(content);
        if (number == null || number <= 0 || number > options.size()) {
            log.warn("DeepSeek é€‰é¡¹åŒ¹é…æœªå‘½ä¸­ï¼ŒvoiceText={}, options={}, modelReturn={}", voiceText, options, content);
            return -1;
        }
        return number - 1;
    }
    /**
     * åˆ¤æ–­è¯­éŸ³æ–‡æœ¬æœ€æŽ¥è¿‘哪个选项,返回选项在列表中的下标。
     *
     * @param questionText è¯­éŸ³è¯†åˆ«å¾—到的文本
     * @param answerText   ç­”案文本
     * @param optionText   é€‰é¡¹æ–‡æœ¬
     * @return å‘½ä¸­é€‰é¡¹çš„下标(从 0 å¼€å§‹ï¼‰ï¼›æ— æ³•匹配任一选项时返回 {@code -1}
     */
    public static int matchQuestionAnswer(String questionText, String answerText, String optionText) {
        if (StringUtils.isBlank(questionText) || StringUtils.isBlank(answerText) || StringUtils.isBlank(optionText)) {
            return -1;
        }
        String systemPrompt = "\"你是一个专业的语音识别文本语义匹配助手。你的任务是判断用户的语音文本在语义上最符合的选项。用户会给出一段语音识别文本和选项文本,"
                + "请判断这段文本在语义上是否匹配选项, åŒ¹é…åˆ™è¾“出 1,没有匹配则输出 0, åªå…è®¸è¾“出1或者0,"
                + "不要做任何解释。直接输出最匹配选项的编号数字;若没有任何选项与文本相关,则输出 0。";
        String userPrompt = "请根据以下信息进行语义匹配判断:\n" +
                "- é—®é¢˜æ–‡æœ¬ï¼š" + questionText + "\n\n"
                + "- è¯­è¨€è¯†åˆ«æ–‡æœ¬ï¼š" + answerText + "\n\n"
                + "- é€‰é¡¹æ–‡æœ¬ï¼š" + optionText + "\n\n"
                + "\n请只输出一个数字(匹配则输出 1,没有匹配则输出 0,只允许输出1或者0)。";
        String content = chatCompletion(systemPrompt, userPrompt);
        if (StringUtils.isBlank(content)) {
            return -1;
        }
        return extractFirstNumber(content);
    }
    /**
     * ä»Žæ¨¡åž‹å›žå¤ä¸­æå–第一个整数。模型偶尔会回复 â€œé€‰é¡¹2” â€œ2。” ä¹‹ç±»ï¼Œåšä¸€æ¬¡å…œåº•解析。
     */
    private static Integer extractFirstNumber(String text) {
        List<Character> digits = new ArrayList<>();
        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);
            if (c >= '0' && c <= '9') {
                digits.add(c);
            } else if (!digits.isEmpty()) {
                break;
            }
        }
        if (digits.isEmpty()) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (char c : digits) {
            sb.append(c);
        }
        try {
            return Integer.parseInt(sb.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }
}
smartor/src/main/java/com/smartor/domain/IvrLibaTemplateScript.java
@@ -356,6 +356,22 @@
    @ApiModelProperty(value = "报备科室编码(如果多个科室用逗号分割)")
    private String reportDeptCode;
    @Excel(name = "责任科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人名称(如果多个科室用逗号分割)")
    private String dutyDeptPersonName;
    @Excel(name = "责任科室责任人编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人编码(如果多个科室用逗号分割)")
    private String dutyDeptPersonCode;
    @Excel(name = "报备科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室名称(如果多个科室用逗号分割)")
    private String reportDeptPersonName;
    @Excel(name = "报备科室编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室责任人编码(如果多个科室用逗号分割)")
    private String reportDeptPersonCode;
//    /**
//     * é—®é¢˜ç»“果(给“值类型”是文本或者数值用的)
//     */
smartor/src/main/java/com/smartor/domain/IvrLibaTemplateScriptVO.java
@@ -388,6 +388,22 @@
    @ApiModelProperty(value = "报备科室编码(如果多个科室用逗号分割)")
    private String reportDeptCode;
    @Excel(name = "责任科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人名称(如果多个科室用逗号分割)")
    private String dutyDeptPersonName;
    @Excel(name = "责任科室责任人编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人编码(如果多个科室用逗号分割)")
    private String dutyDeptPersonCode;
    @Excel(name = "报备科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室名称(如果多个科室用逗号分割)")
    private String reportDeptPersonName;
    @Excel(name = "报备科室编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室责任人编码(如果多个科室用逗号分割)")
    private String reportDeptPersonCode;
    /**
     * è¯æœ¯é€‰é¡¹
     */
smartor/src/main/java/com/smartor/domain/IvrTaskTemplateScript.java
@@ -343,6 +343,22 @@
    @ApiModelProperty(value = "报备科室编码(如果多个科室用逗号分割)")
    private String reportDeptCode;
    @Excel(name = "责任科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人名称(如果多个科室用逗号分割)")
    private String dutyDeptPersonName;
    @Excel(name = "责任科室责任人编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人编码(如果多个科室用逗号分割)")
    private String dutyDeptPersonCode;
    @Excel(name = "报备科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室名称(如果多个科室用逗号分割)")
    private String reportDeptPersonName;
    @Excel(name = "报备科室编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室责任人编码(如果多个科室用逗号分割)")
    private String reportDeptPersonCode;
    /**
     * é—®é¢˜é€‰é¡¹
     */
smartor/src/main/java/com/smartor/domain/IvrTaskTemplateScriptVO.java
@@ -375,6 +375,22 @@
    @ApiModelProperty(value = "报备科室编码(如果多个科室用逗号分割)")
    private String reportDeptCode;
    @Excel(name = "责任科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人名称(如果多个科室用逗号分割)")
    private String dutyDeptPersonName;
    @Excel(name = "责任科室责任人编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人编码(如果多个科室用逗号分割)")
    private String dutyDeptPersonCode;
    @Excel(name = "报备科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室名称(如果多个科室用逗号分割)")
    private String reportDeptPersonName;
    @Excel(name = "报备科室编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室责任人编码(如果多个科室用逗号分割)")
    private String reportDeptPersonCode;
    /**
     * è¯æœ¯é€‰é¡¹
     */
smartor/src/main/java/com/smartor/domain/PatArchive.java
@@ -336,8 +336,8 @@
    /**
     * ä¼šå‘˜å±žæ€§:0非会员,1一般会员、2重要会员
     */
    @ApiModelProperty("会员属性:0非会员,1一般会员、2重要会员")
    @Excel(name = " ä¼šå‘˜å±žæ€§:0非会员,1一般会员、2重要会员 ")
    @ApiModelProperty("会员属性:0非会员,1一般会员、2重要会员 -1虚拟患者")
    @Excel(name = " ä¼šå‘˜å±žæ€§:0非会员,1一般会员、2重要会员 -1虚拟患者")
    private String viptype;
    @ApiModelProperty("出院病区名称")
smartor/src/main/java/com/smartor/domain/ServiceSubtask.java
@@ -451,7 +451,7 @@
     * å°±è¯Šç±»åž‹ï¼ˆ1门诊  2出院)
     */
    @Excel(name = "  å°±è¯Šç±»åž‹ï¼ˆ1门诊  2出院)")
    @ApiModelProperty(value = "就诊类型(1门诊  2出院 3.专病 4.外部导入 5急诊、6住院、7体检)")
    @ApiModelProperty(value = "就诊类型(1门诊  2出院 3.专病 4.外部导入 5急诊、6住院、7体检、8扫码)")
    private String hospType;
smartor/src/main/java/com/smartor/domain/ServiceSubtaskDetailTrace.java
@@ -246,7 +246,7 @@
     * å¤„理详细说明(处理科室)
     */
    @ApiModelProperty("处理详细说明(处理科室)")
    @Excel(name = "处理详细说明", readConverterExp = "处=理科室")
    @Excel(name = "处理详细说明", readConverterExp = "处理科室")
    private String handledesc;
    /**
@@ -360,5 +360,23 @@
    @ApiModelProperty("问题维度")
    private String dimension;
    @Excel(name = "责任科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人名称(如果多个科室用逗号分割)")
    private String dutyDeptPersonName;
    @Excel(name = "责任科室责任人编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人编码(如果多个科室用逗号分割)")
    private String dutyDeptPersonCode;
    @Excel(name = "报备科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室名称(如果多个科室用逗号分割)")
    private String reportDeptPersonName;
    @Excel(name = "报备科室编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室责任人编码(如果多个科室用逗号分割)")
    private String reportDeptPersonCode;
}
smartor/src/main/java/com/smartor/domain/ServiceSubtaskExport.java
@@ -35,6 +35,40 @@
    private String sendname;
    /**
     * å¹´é¾„
     */
    @Excel(name = "年龄 ")
    @ApiModelProperty(value = "年龄")
    private Long age;
    /**
     * æ€§åˆ«
     */
    @ApiModelProperty(value = "性别")
    private Long sex;
    /**
     * æ€§åˆ«
     */
    @Excel(name = "性别")
    @ApiModelProperty(value = "性别")
    private String sexName;
    /**
     * å°±è¯Šç¼–号(对应的outhospno、inhospno)
     */
//    @Excel(name = "就诊编号")
    @ApiModelProperty(value = "就诊编号(对应的outhospno、inhospno)")
    private String hospno;
    /**
     * ç—…历号
     */
    @Excel(name = "病历号")
    @ApiModelProperty(value = "患者编号(病历号)")
    private String patno;
    /**
     * å‡ºé™¢æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
smartor/src/main/java/com/smartor/domain/ServiceSubtaskRes.java
@@ -121,6 +121,13 @@
    private Long sex;
    /**
     * æ€§åˆ«
     */
    @Excel(name = " æ€§åˆ«åç§°")
    @ApiModelProperty(value = "性别名称")
    private String sexName;
    /**
     * å¹´é¾„
     */
    @Excel(name = " å¹´é¾„ ")
@@ -447,6 +454,13 @@
    private String hospno;
    /**
     * æ‚£è€…编号
     */
    @Excel(name = "患者编号(病历号)")
    @ApiModelProperty(value = "患者编号(病历号)")
    private String patno;
    /**
     * å°±è¯Šç±»åž‹ï¼ˆ1门诊  2出院)
     */
    @Excel(name = "  å°±è¯Šç±»åž‹ï¼ˆ1门诊  2出院)")
smartor/src/main/java/com/smartor/domain/ServiceTaskScriptQues.java
@@ -46,6 +46,13 @@
    private String param4;
    /**
     * å­ä»»åŠ¡ID subId
     */
    @Excel(name = "子任务ID subId ")
    @ApiModelProperty(value = "子任务ID subId")
    private String param6;
    /**
     * æ‚£è€…来源
     */
    @Excel(name = "patfrom  ")
smartor/src/main/java/com/smartor/domain/SvyLibTemplateScript.java
@@ -298,6 +298,22 @@
    @ApiModelProperty(value = "报备科室编码(如果多个科室用逗号分割)")
    private String reportDeptCode;
    @Excel(name = "责任科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人名称(如果多个科室用逗号分割)")
    private String dutyDeptPersonName;
    @Excel(name = "责任科室责任人编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人编码(如果多个科室用逗号分割)")
    private String dutyDeptPersonCode;
    @Excel(name = "报备科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室名称(如果多个科室用逗号分割)")
    private String reportDeptPersonName;
    @Excel(name = "报备科室编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室责任人编码(如果多个科室用逗号分割)")
    private String reportDeptPersonCode;
    /**
     * é—®åˆ¸é¢˜ç›®åˆ†ç±»ID集合
     */
smartor/src/main/java/com/smartor/domain/SvyLibTemplateScriptVO.java
@@ -315,6 +315,22 @@
    @ApiModelProperty(value = "报备科室编码(如果多个科室用逗号分割)")
    private String reportDeptCode;
    @Excel(name = "责任科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人名称(如果多个科室用逗号分割)")
    private String dutyDeptPersonName;
    @Excel(name = "责任科室责任人编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人编码(如果多个科室用逗号分割)")
    private String dutyDeptPersonCode;
    @Excel(name = "报备科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室名称(如果多个科室用逗号分割)")
    private String reportDeptPersonName;
    @Excel(name = "报备科室编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室责任人编码(如果多个科室用逗号分割)")
    private String reportDeptPersonCode;
    @Excel(name = "分类ID集合")
    @ApiModelProperty(value = "分类ID集合")
    private List<Long> categoryids;
smartor/src/main/java/com/smartor/domain/SvyTaskTemplate.java
@@ -63,10 +63,10 @@
    private String description;
    /**
     * é—®å·ä»‹ç»
     * é—®å·ä»‹ç»ï¼ˆå½“备注用)
     */
    @Excel(name = " é—®å·ä»‹ç» ")
    @ApiModelProperty(value = "问卷介绍")
    @Excel(name = " é—®å·ä»‹ç»ï¼ˆå½“备注用) ")
    @ApiModelProperty(value = "问卷介绍(当备注用)")
    private String introduce;
    /**
smartor/src/main/java/com/smartor/domain/SvyTaskTemplateScript.java
@@ -262,6 +262,21 @@
    @ApiModelProperty(value = "报备科室编码(如果多个科室用逗号分割)")
    private String reportDeptCode;
    @Excel(name = "责任科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人名称(如果多个科室用逗号分割)")
    private String dutyDeptPersonName;
    @Excel(name = "责任科室责任人编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人编码(如果多个科室用逗号分割)")
    private String dutyDeptPersonCode;
    @Excel(name = "报备科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室名称(如果多个科室用逗号分割)")
    private String reportDeptPersonName;
    @Excel(name = "报备科室编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室责任人编码(如果多个科室用逗号分割)")
    private String reportDeptPersonCode;
    /**
     * é—®åˆ¸é¢˜ç›®åˆ†ç±»ID集合
smartor/src/main/java/com/smartor/domain/SvyTaskTemplateScriptVO.java
@@ -351,6 +351,22 @@
    @ApiModelProperty(value = "报备科室编码(如果多个科室用逗号分割)")
    private String reportDeptCode;
    @Excel(name = "责任科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人名称(如果多个科室用逗号分割)")
    private String dutyDeptPersonName;
    @Excel(name = "责任科室责任人编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人编码(如果多个科室用逗号分割)")
    private String dutyDeptPersonCode;
    @Excel(name = "报备科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室名称(如果多个科室用逗号分割)")
    private String reportDeptPersonName;
    @Excel(name = "报备科室编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室责任人编码(如果多个科室用逗号分割)")
    private String reportDeptPersonCode;
    /**
     * é—®åˆ¸é¢˜ç›®åˆ†ç±»ID集合
     */
smartor/src/main/java/com/smartor/domain/VO/DetailTraceDealVO.java
@@ -34,7 +34,7 @@
    @ApiModelProperty("处理科室名称")
    @Excel(name = "处理科室名称")
    private String todeptname;
    /**
     * é—®é¢˜ç±»åž‹:语音、问卷
     */
@@ -83,5 +83,21 @@
     */
    @ApiModelProperty("问题维度")
    private String dimension;
    @Excel(name = "责任科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人名称(如果多个科室用逗号分割)")
    private String dutyDeptPersonName;
    @Excel(name = "责任科室责任人编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "责任科室责任人编码(如果多个科室用逗号分割)")
    private String dutyDeptPersonCode;
    @Excel(name = "报备科室责任人名称(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室名称(如果多个科室用逗号分割)")
    private String reportDeptPersonName;
    @Excel(name = "报备科室编码(如果多个科室用逗号分割)")
    @ApiModelProperty(value = "报备科室责任人编码(如果多个科室用逗号分割)")
    private String reportDeptPersonCode;
}
smartor/src/main/java/com/smartor/service/IPatMedInhospService.java
@@ -123,4 +123,6 @@
     * @return ç»“æžœ
     */
    public void addOperationSubTask(String config);
    public ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, PatMedInhosp patMedInhosp1, PatArchive patArchive, String config, Integer type);
}
smartor/src/main/java/com/smartor/service/IPatMedOperationService.java
@@ -1,6 +1,9 @@
package com.smartor.service;
import com.smartor.domain.PatArchive;
import com.smartor.domain.PatMedOperation;
import com.smartor.domain.ServiceSubtask;
import com.smartor.domain.ServiceTask;
import java.util.List;
@@ -65,4 +68,6 @@
     * @return
     */
    public int dealOperationInfo();
    public ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, PatMedOperation patMedOperation1, PatArchive patArchive);
}
smartor/src/main/java/com/smartor/service/IPatMedOuthospService.java
@@ -3,9 +3,7 @@
import java.util.List;
import com.ruoyi.common.core.page.TableDataInfo;
import com.smartor.domain.PatMedOuthosp;
import com.smartor.domain.PatMedReq;
import com.smartor.domain.PatMedRes;
import com.smartor.domain.*;
import org.springframework.web.bind.annotation.RequestBody;
/**
@@ -69,4 +67,6 @@
    public PatMedOuthosp getDeptCodeByPatId(PatMedOuthosp patMedOuthosp);
    public Integer dealOutpatientInfo();
    public ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, PatMedOuthosp patMedOuthosp, PatArchive patArchive);
}
smartor/src/main/java/com/smartor/service/IServiceSubtaskService.java
@@ -198,4 +198,6 @@
     * @return
     */
    public List<ServiceSubtaskDetailRatioExport> statQuestionOption(List<Long> taskIds, Date startOutHospTime, Date endOutHospTime);
    public String scanGenerateSubtask(ServiceTask serviceTaskVo);
}
smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java
@@ -956,7 +956,8 @@
    //封装serviceSubtask
    private ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, PatMedInhosp patMedInhosp1, PatArchive patArchive, String config, Integer type) {
    @Override
    public ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, PatMedInhosp patMedInhosp1, PatArchive patArchive, String config, Integer type) {
        //增加serviceTask判空
//        if(Objects.isNull(serviceTask)){
//            return null;
@@ -994,6 +995,7 @@
        serviceSubtask.setSex(patArchive.getSex());
        serviceSubtask.setAge(patArchive.getAge());
        serviceSubtask.setSendstate(2L);
        serviceSubtask.setCampusid(patMedInhosp1.getCampusid());
        serviceSubtask.setManagementDoctor(patMedInhosp1.getManagementDoctor());
        serviceSubtask.setManagementDoctorCode(patMedInhosp1.getManagementDoctorCode());
        serviceSubtask.setStarttime(patMedInhosp1.getStarttime());
smartor/src/main/java/com/smartor/service/impl/PatMedOperationServiceImpl.java
@@ -185,7 +185,8 @@
    }
    //封装serviceSubtask
    private ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, PatMedOperation patMedOperation1, PatArchive patArchive) {
    @Override
    public ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, PatMedOperation patMedOperation1, PatArchive patArchive) {
        ServiceSubtask serviceSubtask = DtoConversionUtils.sourceToTarget(serviceTask, ServiceSubtask.class);
        serviceSubtask.setTaskid(serviceTask.getTaskid());
        if (StringUtils.isNotEmpty(serviceTask.getLibtemplateid()))
smartor/src/main/java/com/smartor/service/impl/PatMedOuthospServiceImpl.java
@@ -475,7 +475,8 @@
    }
    //封装serviceSubtask
    private ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, PatMedOuthosp patMedOuthosp, PatArchive patArchive) {
    @Override
    public ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, PatMedOuthosp patMedOuthosp, PatArchive patArchive) {
        ServiceSubtask serviceSubtask = DtoConversionUtils.sourceToTarget(serviceTask, ServiceSubtask.class);
        serviceSubtask.setTaskid(serviceTask.getTaskid());
        if (StringUtils.isNotEmpty(serviceTask.getLibtemplateid()))
smartor/src/main/java/com/smartor/service/impl/ServiceExternalServiceImpl.java
@@ -1,8 +1,6 @@
package com.smartor.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ruoyi.common.core.domain.entity.SysDept;
@@ -10,8 +8,6 @@
import com.ruoyi.common.core.domain.entity.SysUserDept;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.AesUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DtoConversionUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
@@ -21,7 +17,6 @@
import com.smartor.service.IPatMedOuthospService;
import com.smartor.service.IServiceExternalService;
import lombok.extern.slf4j.Slf4j;
import netscape.javascript.JSObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -30,8 +25,6 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
@@ -435,6 +428,7 @@
        Map yeWuXX = (Map) dataMap.get("YeWuXX");
        Map<String, Object> BingRenXX = ObjectUtils.isNotEmpty(yeWuXX) ? (Map<String, Object>) yeWuXX.get("BingRenXX") : null;
        Map<String, Object> RuKeXX = ObjectUtils.isNotEmpty(yeWuXX) ? (Map<String, Object>) yeWuXX.get("RuKeXX") : null;
        Map<String, Object> JiuZhenXX = ObjectUtils.isNotEmpty(yeWuXX) ? (Map<String, Object>) yeWuXX.get("JiuZhenXX") : null;
        List<HashMap<String, Object>> epai = ObjectUtils.isNotEmpty(yeWuXX) ? (List<HashMap<String, Object>>) BingRenXX.get("DiZhiXXList") : null;
@@ -445,8 +439,6 @@
        externalInHospPatientInfo.setZhuZhiYSID(externalInDeptPatientInfo.getZhuZhiYSID());
        externalInHospPatientInfo.setZhuZhiYSXM(externalInDeptPatientInfo.getZhuZhiYSXM());
        externalInHospPatientInfo.setRuYuanSJ(externalInDeptPatientInfo.getRuYuanSJ());
        externalInHospPatientInfo.setJingGuanYSID(externalInDeptPatientInfo.getJingGuanYSID());
        externalInHospPatientInfo.setJingGuanYSXM(externalInDeptPatientInfo.getJingGuanYSXM());
        externalInHospPatientInfo.setLianXiDH(ObjectUtils.isNotEmpty(BingRenXX.get("LianXiDH")) ? BingRenXX.get("LianXiDH").toString() : null);
        externalInHospPatientInfo.setDangQianCWID(ObjectUtils.isNotEmpty(BingRenXX.get("DangQianCWID")) ? BingRenXX.get("DangQianCWID").toString() : null);
        externalInHospPatientInfo.setDangQianCWMC(ObjectUtils.isNotEmpty(BingRenXX.get("DangQianCWMC")) ? BingRenXX.get("DangQianCWMC").toString() : null);
@@ -517,13 +509,20 @@
        Map yeWuXX = (Map) dataMap.get("YeWuXX");
        Map<String, Object> BingRenXX = ObjectUtils.isNotEmpty(yeWuXX) ? (Map<String, Object>) yeWuXX.get("BingRenXX") : null;
        Map<String, Object> ChuYuanJL = ObjectUtils.isNotEmpty(yeWuXX) ? (Map<String, Object>) yeWuXX.get("ChuYuanJL") : null;
        Map<String, Object> JiuZhenXX = ObjectUtils.isNotEmpty(yeWuXX) ? (Map<String, Object>) yeWuXX.get("JiuZhenXX") : null;
        List<HashMap<String, Object>> epai = ObjectUtils.isNotEmpty(BingRenXX) ? (List<HashMap<String, Object>>) BingRenXX.get("DiZhiXXList") : null;
        List<HashMap<String, Object>> epli = ObjectUtils.isNotEmpty(yeWuXX) ? (List<HashMap<String, Object>>) yeWuXX.get("LianXiRList") : null;
        Map<String, Object> SuiFangJH = ObjectUtils.isNotEmpty(ChuYuanJL) ? (Map<String, Object>) ChuYuanJL.get("SuiFangJH") : null;
        ExternalInHospPatientInfo externalInHospPatientInfo = BeanUtil.mapToBean(BingRenXX, ExternalInHospPatientInfo.class, true);
        ExternalInHospPatientAddrInfo externalInHospPatientAddrInfo = null;
        ExternalInHospPatientLiaisonInfo externalInHospPatientLiaisonInfo = null;
        //就诊信息
        ExternalInDeptPatientInfo externalJZInfo = BeanUtil.mapToBean(JiuZhenXX, ExternalInDeptPatientInfo.class, true);
        if(ObjectUtils.isNotEmpty(externalJZInfo)){
            externalInHospPatientInfo.setJingGuanYSID(externalJZInfo.getJingGuanYSID());
            externalInHospPatientInfo.setJingGuanYSXM(externalJZInfo.getJingGuanYSXM());
        }
        List<ExternalInHospPatientAddrInfo> epai2 = null;
        //死亡标记
        Boolean deathFlag = false;
@@ -582,7 +581,6 @@
            String tagname = patMedInhospMapper.getTagnameBypatid(patMedInhosp1.getPatid());
            patMedInhosp1.setTagname(tagname);
        }
        Map<String, Object> JiuZhenXX = ObjectUtils.isNotEmpty(yeWuXX) ? (Map<String, Object>) yeWuXX.get("JiuZhenXX") : null;
        PatMedInhosp patMedInhosp1 = new PatMedInhosp();
        if (CollectionUtils.isNotEmpty(patMedInhospList)) patMedInhosp1 = patMedInhospList.get(0);
        patMedInhosp1.setSchemestatus(2L);
@@ -599,6 +597,9 @@
            patMedInhosp1.setNurseName(ObjectUtils.isNotEmpty(JiuZhenXX.get("ZeRenHSXM")) ? JiuZhenXX.get("ZeRenHSXM").toString() : null);
            patMedInhosp1.setNurseId(ObjectUtils.isNotEmpty(JiuZhenXX.get("ZeRenHSID")) ? JiuZhenXX.get("ZeRenHSID").toString() : null);
            patMedInhosp1.setBedNo(ObjectUtils.isNotEmpty(JiuZhenXX.get("DangQianCWMC")) ? JiuZhenXX.get("DangQianCWMC").toString() : null);
            patMedInhosp1.setManagementDoctorCode(ObjectUtils.isNotEmpty(JiuZhenXX.get("JingGuanYSID")) ? JiuZhenXX.get("JingGuanYSID").toString() : null);
            patMedInhosp1.setManagementDoctor(ObjectUtils.isNotEmpty(JiuZhenXX.get("JingGuanYSXM")) ? JiuZhenXX.get("JingGuanYSXM").toString() : null);
            //离院方式代码 1-医瞩离院 2-医嘱转院 3-医嘱转社区卫生服务机构/乡镇卫生院
            // 4-非医嘱离院 5-死亡 9-其他 10-介入室 20-手术室
@@ -982,6 +983,9 @@
            patMedInhosp1.setNurseName(ObjectUtils.isNotEmpty(JiuZhenXX.get("ZeRenHSXM")) ? JiuZhenXX.get("ZeRenHSXM").toString() : null);
            patMedInhosp1.setNurseId(ObjectUtils.isNotEmpty(JiuZhenXX.get("ZeRenHSID")) ? JiuZhenXX.get("ZeRenHSID").toString() : null);
            patMedInhosp1.setBedNo(ObjectUtils.isNotEmpty(JiuZhenXX.get("DangQianCWMC")) ? JiuZhenXX.get("DangQianCWMC").toString() : null);
            patMedInhosp1.setManagementDoctorCode(ObjectUtils.isNotEmpty(JiuZhenXX.get("JingGuanYSID")) ? JiuZhenXX.get("JingGuanYSID").toString() : null);
            patMedInhosp1.setManagementDoctor(ObjectUtils.isNotEmpty(JiuZhenXX.get("JingGuanYSXM")) ? JiuZhenXX.get("JingGuanYSXM").toString() : null);
        }
        patMedInhosp1.setUpdateTime(new Date());
        patMedInhosp1.setTelcode(patArchive.getTelcode());
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskAnswerServiceImpl.java
@@ -15,7 +15,6 @@
import com.smartor.domain.entity.ServiceSubtaskEntity;
import com.smartor.mapper.*;
import com.smartor.service.*;
import com.sun.org.apache.bcel.internal.generic.NEW;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
@@ -1020,6 +1019,10 @@
            subtaskDetailTrace.setCreateTime(new Date());
            subtaskDetailTrace.setUpdateTime(new Date());
            subtaskDetailTrace.setOrgid(selectServiceSubtaskList.get(0).getOrgid());
            subtaskDetailTrace.setDutyDeptPersonCode(svyTaskTemplateScriptVO.getDutyDeptPersonCode());
            subtaskDetailTrace.setDutyDeptPersonName(svyTaskTemplateScriptVO.getDutyDeptPersonName());
            subtaskDetailTrace.setReportDeptPersonCode(svyTaskTemplateScriptVO.getReportDeptPersonCode());
            subtaskDetailTrace.setReportDeptPersonName(svyTaskTemplateScriptVO.getReportDeptPersonName());
            Long existTraceId = existingTraceIdMap.get(subtaskDetailTrace.getScriptid());
            if (existTraceId != null) {
@@ -1293,6 +1296,10 @@
            subtaskDetailTrace.setCreateTime(new Date());
            subtaskDetailTrace.setUpdateTime(new Date());
            subtaskDetailTrace.setOrgid(selectServiceSubtaskList.get(0).getOrgid());
            subtaskDetailTrace.setDutyDeptPersonCode(ivrTaskTemplateScriptVO.getDutyDeptPersonCode());
            subtaskDetailTrace.setDutyDeptPersonName(ivrTaskTemplateScriptVO.getDutyDeptPersonName());
            subtaskDetailTrace.setReportDeptPersonCode(ivrTaskTemplateScriptVO.getReportDeptPersonCode());
            subtaskDetailTrace.setReportDeptPersonName(ivrTaskTemplateScriptVO.getReportDeptPersonName());
            ServiceSubtaskDetailTraceVO ssdt = new ServiceSubtaskDetailTraceVO();
            ssdt.setSubId(subtaskDetailTrace.getSubId());
@@ -1303,6 +1310,7 @@
                subtaskDetailTrace.setId(serviceSubtaskDetailTraces.get(0).getId());
                traceService.updateServiceSubtaskDetailTtrace(subtaskDetailTrace);
            } else traceService.insertServiceSubtaskDetailTtrace(subtaskDetailTrace);
        } else if (stt != null && stt.getIsabnormal() != null && stt.getIsabnormal() != 1L) {
            //这里主要是怕医护人员把异常选项改成了非异常的,这里就需要查一下这条数据是不是在满意度异常表,如果在,则要删除
            ServiceSubtaskDetailTraceVO subtaskDetailTraceVO = new ServiceSubtaskDetailTraceVO();
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -6,15 +6,19 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.dx.MessageSend;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.core.service.IConfigService;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.service.ISysConfigService;
import com.smartor.common.DeepSeekApi;
import com.smartor.common.FtpService;
import com.smartor.common.MtSubmitSmUtil;
import com.smartor.common.ScheduleSubtaskBuilder;
@@ -31,6 +35,7 @@
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.ibatis.annotations.Param;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
@@ -38,17 +43,17 @@
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
@@ -139,6 +144,9 @@
    @Autowired
    private SvyLibScriptCategoryMapper svyLibScriptCategoryMapper;
    @Autowired
    private IPatMedInhospService patMedInhospService;
    @Value("${pri_key}")
    private String pri_key;
@@ -147,6 +155,9 @@
    @Value("${ASRCallBackPath}")
    private String ASRCallBackPath;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private MtSubmitSmUtil mtSubmitSmUtil;
@@ -420,9 +431,74 @@
                    serviceSubtaskRes.setCurrentPreachform(serviceSubtask.getPreachform().split(",")[0]);
                }
            }
            PatMedInhosp inhosp = patMedInhospMapper.selectPatMedInhospByInhospid(serviceSubtask.getInhospid());
            if (ObjectUtils.isNotEmpty(inhosp)) {
                PatArchive patArchive = patArchiveMapper.selectPatArchiveByPatid(inhosp.getPatid());
                if (ObjectUtils.isNotEmpty(patArchive)) {
                    Map<String, String> stringStringMap = calculateAge(patArchive.getBirthdate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(), LocalDate.now());
                    serviceSubtaskRes.setAge(StringUtils.isNotEmpty(stringStringMap.get("age")) ? Long.valueOf(stringStringMap.get("age")) : null);
                    serviceSubtaskRes.setSex(patArchive.getSex());
                    serviceSubtaskRes.setSexName(patArchive.getSex() != null ? (patArchive.getSex() == 1 ? "男" : "女") : null);
                }
                serviceSubtaskRes.setHospno(inhosp.getInhospno());
                serviceSubtaskRes.setPatno(inhosp.getPatno());
            }
            serviceSubtaskResList.add(serviceSubtaskRes);
        }
        return serviceSubtaskResList;
    }
    public Map<String, String> calculateAge(LocalDate birthdate, LocalDate today) {
        if (birthdate == null || today.isBefore(birthdate)) {
            return null;
        }
        Map<String, String> ageMap = new HashMap<>();
        Period period = Period.between(birthdate, today);
        long totalDays = ChronoUnit.DAYS.between(birthdate, today);
        long totalMonths = ChronoUnit.MONTHS.between(birthdate, today);
        int years = period.getYears();
        int months = period.getMonths();
        int days = period.getDays();
        String ageUnit;
        Integer age;
        String ageUnit2 = null;
        Integer age2 = null;
        if (totalDays < 90) {
            // å°äºŽ 1 ä¸ªæœˆï¼ŒæŒ‰å¤©è®¡ç®—
            ageUnit = "天";
            age = (int) totalDays;
            ageMap.put("age", age != null ? age.toString() : null);
            ageMap.put("ageUnit", ageUnit);
            ageMap.put("age2", null);
            ageMap.put("ageUnit2", null);
        } else if (totalMonths < 36) {
            // å°äºŽ 1 å¹´ï¼ŒæŒ‰æœˆ + å¤©è®¡ç®—
            ageUnit = "月";
            age = (int) totalMonths;
            ageUnit2 = "天";
            age2 = days;
            ageMap.put("age", age != null ? age.toString() : null);
            ageMap.put("ageUnit", ageUnit);
            ageMap.put("age2", age2 != null ? age2.toString() : null);
            ageMap.put("ageUnit2", ageUnit2);
        } else {
            // å¤§äºŽ 1 å¹´ï¼ŒæŒ‰å¹´ + æœˆè®¡ç®—
            ageUnit = "岁";
            age = years;
            ageUnit2 = "月";
            age2 = months;
            ageMap.put("age", age != null ? age.toString() : null);
            ageMap.put("ageUnit", ageUnit);
            ageMap.put("age2", age2 != null ? age2.toString() : null);
            ageMap.put("ageUnit2", ageUnit2);
        }
        return ageMap;
    }
    @Override
@@ -594,9 +670,16 @@
        ServiceSubtask serviceSubtask = serviceSubtaskMapper.selectServiceSubtaskById(serviceSubtaskTemplateVO.getSubId());
        if (serviceSubtask == null || serviceSubtask.getSendstate() != 2L)
            throw new BaseException("该任务已发送给患者,不能再进行修改模板");
        serviceSubtaskTemplateVO.getSvyTaskTemplateVO().setIntroduce("该问卷是替换后的问题,替换前的问题是:" + serviceSubtask.getTemplateid());
        Integer taskTempid = svyTaskTemplateService.saveOrUpdateTemplate(serviceSubtaskTemplateVO.getSvyTaskTemplateVO());
        if (taskTempid == null) return false;
        //每次都新建一个也可以,但新建之后要把之前的删除
        if (serviceSubtask.getType().equals("2")) {
            svyTaskTemplateService.deleteSvyTaskTemplateBySvyid(serviceSubtask.getTemplateid());
        } else if (serviceSubtask.getType().equals("1"))
            ivrTaskTemplateService.deleteIvrTaskTemplateByID(serviceSubtask.getTemplateid());
        String tempName = svyTaskTemplateService.selectSvyTaskTemplateBySvyid(Long.valueOf(taskTempid)).getSvyname();
        serviceSubtask.setTemplateid(taskTempid.longValue());
@@ -1731,12 +1814,28 @@
            if (ivrTaskTemplateScriptVO.getScriptType().equals("1")) {
                //用来标记,是否有匹配上的
                Integer flag = 0;
                //1-AI识别
                SysConfig configVoiceMatchAi = new SysConfig();
                configVoiceMatchAi.setOrgid(phoneCallReqYQVO.getOrgid());
                configVoiceMatchAi.setConfigKey("sys.voice.match.ai");
                SysConfig matchAi = sysConfigMapper.selectConfig(configVoiceMatchAi);
//            if (ObjectUtils.isNotEmpty(matchAi) && StringUtils.isNotEmpty(matchAi.getConfigValue())
//                    && matchAi.getConfigValue().equals("1")) {
//                PhoneCallBackYQVO aiMatchResult = AiMatch(phoneCallReqYQVO, phoneCallBackYQVO,
//                        ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate,
//                        ivrTaskTemplateScripts, scriptId, flag);
//                if(aiMatchResult != null){
//                    return aiMatchResult;
//                }
//            } else {
                //是选择题
                for (int j = 0; j < ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().size(); j++) {
                    log.error("phoneCallReqYQVO.getAsrtext()的值为:{}", phoneCallReqYQVO.getAsrtext());
                    if (StringUtils.isEmpty(phoneCallReqYQVO.getAsrtext())) {
                        continue;
                    }
                    boolean matchedFlag = false;
                    //包含
                    Matcher matcher = null;
                    if (StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex())) {
@@ -1749,8 +1848,12 @@
                        Pattern pattern2 = Pattern.compile(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2());
                        matcher2 = pattern2.matcher(phoneCallReqYQVO.getAsrtext());
                    }
                    if (StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2()) && matcher2.matches() && StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex()) && matcher.matches() || StringUtils.isEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex()) && StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2()) && matcher2.matches() || StringUtils.isEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2()) && StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex()) && matcher.matches()) {
                        //说明匹配正确了
                        matchedFlag = true;
                    }
                    //说明匹配正确了
                    if(matchedFlag){
                        //这里应该先判断类型,去再修改,设置IsUserOperation是单选题的改法
                        log.info("匹配正确了吗--------------");
                        ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).setIsUserOperation(1);
@@ -1967,6 +2070,7 @@
                        continue;
                    }
                }
//            }
                //都没有匹配到
                if (StringUtils.isEmpty(phoneCallBackYQVO.getValue())) {
                    log.info("都没有匹配到-------------------------");
@@ -4615,9 +4719,9 @@
    }
    @Override
    public List<ServiceSubtask> gethelibraryCountHyperlink(HeLibraryCountVO heLibraryCountVO){
    public List<ServiceSubtask> gethelibraryCountHyperlink(HeLibraryCountVO heLibraryCountVO) {
        String hyperLinkInfoType = heLibraryCountVO.getHyperLinkInfoType();
        if(StringUtils.isNotEmpty(hyperLinkInfoType)){
        if (StringUtils.isNotEmpty(hyperLinkInfoType)) {
            heLibraryCountVO.setSendstate(null);
            heLibraryCountVO.setIsFinished(null);
            switch (hyperLinkInfoType) {
@@ -4840,4 +4944,396 @@
        }
    }
    public String scanGenerateSubtask(ServiceTask serviceTaskVo) {
        String content = "";
        String ip = localIP;
        ServiceTask serviceTask = new ServiceTask();
        serviceTask = serviceTaskService.selectServiceTaskByTaskid(serviceTaskVo.getTaskid());
        if (ObjectUtils.isNotEmpty(serviceTask)) {
            try {
                ServiceTaskdept serviceTaskdept = new ServiceTaskdept();
                if (ObjectUtils.isNotEmpty(serviceTaskVo.getDeptcode())) {
                    serviceTaskdept.setDeptType("1");
                    serviceTaskdept.setDeptCode(serviceTaskVo.getDeptcode());
                }
                if (ObjectUtils.isNotEmpty(serviceTaskVo.getLeavehospitaldistrictcode())) {
                    serviceTaskdept.setDeptType("2");
                    serviceTaskdept.setDeptCode(serviceTaskVo.getLeavehospitaldistrictcode());
                }
                serviceTaskdept.setServiceType(serviceTask.getServiceType());
                serviceTaskdept.setOrgid(serviceTask.getOrgid());
                serviceTaskdept.setTaskId(serviceTaskVo.getTaskid());
                List<ServiceTaskdept> serviceTaskdepts = serviceTaskdeptService.selectServiceTaskdeptList(serviceTaskdept);
                if (!CollectionUtils.isEmpty(serviceTaskdepts)) {
                    PatArchive patArchive = new PatArchive();
                    patArchive.setId(999999999L);
                    patArchive.setName("虚拟患者");
                    //封装serviceSubtask
                    ServiceSubtask serviceSubtask = boxedServiceSubtask(serviceTask, serviceTaskdepts.get(0), patArchive);
                    int i = serviceSubtaskMapper.insertServiceSubtask(serviceSubtask);
                    //根据生成外链
                    if (ObjectUtils.isNotEmpty(serviceSubtask.getTaskid()) && ObjectUtils.isNotEmpty(serviceSubtask.getPatid()) && ObjectUtils.isNotEmpty(serviceSubtask.getId())) {
                        RSAPublicKeyExample rsaPublicKeyExample = new RSAPublicKeyExample();
                        String taskId = rsaPublicKeyExample.encryptedData(serviceSubtask.getTaskid().toString(), pub_key);
                        String patid = rsaPublicKeyExample.encryptedData(serviceSubtask.getPatid().toString(), pub_key);
                        String subId = rsaPublicKeyExample.encryptedData(serviceSubtask.getId().toString(), pub_key);
                        ServiceOutPath serviceOutPath = new ServiceOutPath();
                        serviceOutPath.setParam1(taskId);
                        serviceOutPath.setParam2(patid);
                        serviceOutPath.setParam3(serviceTask.getTaskName());
                        serviceOutPath.setParam6(subId);
                        serviceOutPath.setCreateTime(new Date());
                        serviceOutPath.setOrgid(serviceTask.getOrgid());
                        iServiceOutPathService.insertServiceOutPath(serviceOutPath);
                        String format = String.format("%03X", serviceOutPath.getId());
                        serviceOutPath.setRadix(format);
                        serviceOutPath.setUpdateTime(new Date());
                        String url = ip + ":" + req_path + "/wt?p=" + format;
                        content = url;
                        serviceOutPath.setUrl(url);
                        iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("【扫码生成任务】处理异常:{}", e.getMessage());
            }
        }
        return content;
    }
    public ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, ServiceTaskdept serviceTaskdept, PatArchive patArchive) {
        ServiceSubtask serviceSubtask = DtoConversionUtils.sourceToTarget(serviceTask, ServiceSubtask.class);
        serviceSubtask.setTaskid(serviceTask.getTaskid());
        if (StringUtils.isNotEmpty(serviceTask.getLibtemplateid()))
            serviceSubtask.setLibtemplateid(Long.valueOf(serviceTask.getLibtemplateid()));
//        serviceSubtask.setNurseId(patMedInhosp1.getNurseId());
//        serviceSubtask.setNurseName(patMedInhosp1.getNurseName());
//        serviceSubtask.setDrcode(patMedInhosp1.getDrcode());
//        serviceSubtask.setDrname(patMedInhosp1.getDrname());
        if(StringUtils.isNotEmpty(serviceTaskdept.getDeptType()) && serviceTaskdept.getDeptType().equals("1")){
            serviceSubtask.setDeptcode(serviceTaskdept.getDeptCode());
            serviceSubtask.setDeptname(serviceTaskdept.getDeptName());
        }else {
            serviceSubtask.setLeavehospitaldistrictcode(serviceTaskdept.getDeptCode());
            serviceSubtask.setLeavehospitaldistrictname(serviceTaskdept.getDeptName());
        }
        serviceSubtask.setTemplateid(serviceTask.getTemplateid());
        serviceSubtask.setTemplatename(serviceTask.getTemplatename());
        serviceSubtask.setPatid(patArchive.getId());
        serviceSubtask.setSendname(patArchive.getName());
        serviceSubtask.setSfzh(patArchive.getIdcardno());
        serviceSubtask.setPhone(patArchive.getTelcode());
        if (StringUtils.isBlank(patArchive.getTelcode())) serviceSubtask.setPhone(patArchive.getRelativetelcode());
        serviceSubtask.setSex(patArchive.getSex());
        serviceSubtask.setAge(patArchive.getAge());
        serviceSubtask.setSendstate(3L);
//        serviceSubtask.setManagementDoctor(patMedInhosp1.getManagementDoctor());
//        serviceSubtask.setManagementDoctorCode(patMedInhosp1.getManagementDoctorCode());
        serviceSubtask.setServiceType(serviceTask.getServiceType());
        serviceSubtask.setPreachform(serviceTask.getPreachform());
        serviceSubtask.setHospType("8");
        serviceSubtask.setCreateTime(new Date());
        serviceSubtask.setUpdateTime(new Date());
//        serviceSubtask.setCreateBy(patMedInhosp1.getNurseName());
//        serviceSubtask.setLeavehospitaldistrictcode(patMedInhosp1.getLeavehospitaldistrictcode());
//        serviceSubtask.setLeavehospitaldistrictname(patMedInhosp1.getLeavehospitaldistrictname());
        serviceSubtask.setUpdateBy(serviceTask.getUpdateBy());
        serviceSubtask.setUpdateTime(new Date());
        serviceTask.setSendDay(1L);
        Date newDate = new Date();
        serviceSubtask.setLongSendTime(newDate);
        serviceSubtask.setVisitTime(newDate);
        return serviceSubtask;
    }
    /**
     * Ai åŒ¹é…é€‰é¡¹
     * @param questionText
     * @param voiceText
     * @param options
     * @return
     */
    public Integer matchOptionIndex(String questionText, String voiceText, List<IvrTaskTemplateTargetoption> options){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userQuestion",questionText);
        jsonObject.put("userAnswer",voiceText);
        jsonObject.put("options", options);
        String jsonString = jsonObject.toJSONString();
        String result = null;
        String url = "http://localhost:8099/matchOptionIndex";
//        String url = configService.selectConfigByKey("sys.voice.match.ai.url");
        if(StringUtils.isNotEmpty(url)){
            try {
                Map<String, String> headers = new HashMap<>();
                headers.put("Content-Type", "application/json");
                result = HttpUtils.sendPostByHeader(url, jsonString, headers);
            } catch (Exception e) {
                log.error("AI识别失败", e);
            }
        }
        if(StringUtils.isNotEmpty(result) && result.matches("^-?\\d+$")){
            return Integer.parseInt(result);
        }else {
            return -1;
        }
    }
    public PhoneCallBackYQVO AiMatch(PhoneCallReqYQVO phoneCallReqYQVO, PhoneCallBackYQVO phoneCallBackYQVO,
                        IvrTaskTemplateScriptVO ivrTaskTemplateScriptVO, ServiceSubtask serviceSubtask, IvrTaskTemplate ivrTaskTemplate,
                        List<IvrTaskTemplateScript> ivrTaskTemplateScripts, String scriptId, Integer flag){
        PhoneCallBackYQVO back = null;
        List<IvrTaskTemplateTargetoption> options = ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList();
        String voiceText = phoneCallReqYQVO.getAsrtext();
        String questionText = StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrtext()) ? ivrTaskTemplateScriptVO.getIvrtext() : ivrTaskTemplateScriptVO.getScriptContent();
        Integer matched = -1;
        matched = matchOptionIndex(questionText, voiceText, options);
        //说明匹配正确了
        if(matched != null && matched >= 0){
            IvrTaskTemplateTargetoption chosenOption = options.get(matched);
            //这里应该先判断类型,去再修改,设置IsUserOperation是单选题的改法
            log.info("匹配正确了吗--------------");
            chosenOption.setIsUserOperation(1);
            serviceTaskScriptTargetoptionMapper.updateIvrTaskTemplateTargetoption(chosenOption);
            //将患者的回签写进service_subtask_detail中
            ServiceSubTaskDetailReq serviceSubTaskDetailReq = new ServiceSubTaskDetailReq();
            List<ServiceSubtaskDetail> serviceSubtaskDetailList = new ArrayList<>();
            ivrTaskTemplateScriptVO.setQuestionResult(chosenOption.getOptiondesc());
            ServiceSubtaskDetail serviceSubtaskDetail = getServiceSubtaskDetail(phoneCallReqYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate);
            //修改一下语音路径(改成前端可以访问的,存到数据库中)
            if (StringUtils.isNotEmpty(serviceSubtaskDetail.getQuestionvoice())) {
                String questionvoice = serviceSubtaskDetail.getQuestionvoice();
                String[] split = questionvoice.split("\\\\");
                if (split.length > 0) {
                    String lastPart = split[split.length - 1];
                    serviceSubtaskDetail.setQuestionvoice(voicePathPrefix + lastPart);
                }
            }
            serviceSubtaskDetailList.add(serviceSubtaskDetail);
            serviceSubTaskDetailReq.setServiceSubtaskDetailList(serviceSubtaskDetailList);
            serviceSubTaskDetailReq.setGuid(phoneCallReqYQVO.getGuid());
            serviceSubTaskDetailReq.setOrgid(phoneCallReqYQVO.getOrgid());
            saveQuestionAnswerPhone(serviceSubTaskDetailReq);
            //判断一下当前的问题是不是满意度问题,并且dutyDeptCode是否有值,并且选项是不是异常选项,如果全符合,则往满意度问题异常表新增
            if (StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getDutyDeptCode()) && 1 == chosenOption.getIsabnormal()) {
                ServiceSubtaskDetailTrace subtaskDetailTrace = new ServiceSubtaskDetailTrace();
                //用taskid、subid和scriptid去获取detailid
                ServiceSubtaskDetail ssd = new ServiceSubtaskDetail();
                ssd.setSubId(serviceSubtask.getId());
                ssd.setTaskid(serviceSubtask.getTaskid());
                ssd.setScriptid(StringUtils.isNotEmpty(scriptId) ? Long.valueOf(scriptId) : null);
                List<ServiceSubtaskDetail> serviceSubtaskDetails = serviceSubtaskDetailMapper.selectServiceSubtaskDetailList(ssd);
                subtaskDetailTrace.setDetailId(CollectionUtils.isNotEmpty(serviceSubtaskDetails) ? serviceSubtaskDetails.get(0).getId() : null);
                subtaskDetailTrace.setSubId(serviceSubtask.getId());
                subtaskDetailTrace.setTaskid(serviceSubtask.getTaskid());
                subtaskDetailTrace.setTemplateid(ivrTaskTemplateScriptVO.getId());
                subtaskDetailTrace.setTemplatequestionnum(ivrTaskTemplateScriptVO.getScriptno());
                subtaskDetailTrace.setSwitchid(chosenOption.getId());
                subtaskDetailTrace.setQuestiontext(ivrTaskTemplateScriptVO.getScriptContent());
                subtaskDetailTrace.setQuestionvoice(null);
                subtaskDetailTrace.setCategoryname(ivrTaskTemplateScriptVO.getScriptAssortname());
                subtaskDetailTrace.setCategoryid(ivrTaskTemplateScriptVO.getScriptAssortid());
                //获取所有选项
                String optionDescStr = Optional.ofNullable(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList()).filter(list -> !list.isEmpty()).map(list -> list.stream().map(IvrTaskTemplateTargetoption::getOptiondesc).filter(Objects::nonNull).collect(Collectors.joining("&"))).orElse("");
                subtaskDetailTrace.setTargetid(chosenOption.getId());
                subtaskDetailTrace.setTargetvalue(optionDescStr);
                subtaskDetailTrace.setMatchedtext(chosenOption.getOptiondesc());
                subtaskDetailTrace.setValueType(serviceSubtaskDetails.get(0).getValueType());
                subtaskDetailTrace.setTemplateType(1);
                SvyLibScriptCategory svyLibScriptCategory = svyLibScriptCategoryMapper.selectSvyLibScriptCategoryById(ivrTaskTemplateScriptVO.getScriptAssortid());
                subtaskDetailTrace.setType(svyLibScriptCategory.getType());
                subtaskDetailTrace.setScriptid(ivrTaskTemplateScriptVO.getId());
                subtaskDetailTrace.setAsrtext(phoneCallReqYQVO.getAsrtext());
                subtaskDetailTrace.setRecordpath(phoneCallReqYQVO.getRecordpath());
                subtaskDetailTrace.setPatid(serviceSubtask.getPatid());
                JSONObject patdescJson = new JSONObject();
                patdescJson.put("sendname", serviceSubtask.getSendname());
                patdescJson.put("phone", serviceSubtask.getPhone());
                patdescJson.put("age", serviceSubtask.getAge());
                patdescJson.put("sex", serviceSubtask.getSex() != null ? serviceSubtask.getSex() == 1 ? "男" : "女" : null);
                subtaskDetailTrace.setPatdesc(patdescJson.toJSONString());
                subtaskDetailTrace.setTodeptcode(ivrTaskTemplateScriptVO.getDutyDeptCode());
                subtaskDetailTrace.setTodeptname(ivrTaskTemplateScriptVO.getDutyDeptName());
                subtaskDetailTrace.setOrgid(serviceSubtask.getOrgid());
                subtaskDetailTrace.setHandleFlag("0");
                subtaskDetailTrace.setGuid(phoneCallReqYQVO.getGuid());
                subtaskDetailTrace.setCreateTime(new Date());
                subtaskDetailTrace.setUpdateTime(new Date());
                subtaskDetailTrace.setOrgid(phoneCallReqYQVO.getOrgid());
                traceService.insertServiceSubtaskDetailTtrace(subtaskDetailTrace);
            }
            //判断一下,这个选项结果是不是还有继续问下去的必要,例如选项结果是别人不想继续回答问题,就要结束掉
            if (chosenOption.getIsEnd() == 1) {
                redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
                redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
                redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
                redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "noVoice");
                //在redis中保存一下结束语,在调用挂电话的方法时删除
                ServiceTask serviceTask = serviceTaskService.selectServiceTaskByTaskid(serviceSubtask.getTaskid());
                redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
                phoneCallBackYQVO.setType("text");
                phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + serviceTask.getJsy());
                //记录状态
                setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
                return phoneCallBackYQVO;
            }
            flag = 1;
            //将当前前的播报状态删除,给下一题让位
            redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
//                        //获取下一题
            log.error("获取下一题的信息:{}", ivrTaskTemplateScriptVO);
            if (ivrTaskTemplateScriptVO.getBranchFlag().equals("1") || ivrTaskTemplateScriptVO.getBranchFlag().equals("0") && ivrTaskTemplateScriptVO.getNextScriptno() != null && ivrTaskTemplateScriptVO.getNextScriptno() != 0) {
                Long nextQuestion = null;
                if (ivrTaskTemplateScriptVO.getBranchFlag().equals("1")) {
                    nextQuestion = chosenOption.getNextQuestion();
                    //更新分数
                    double score = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
                    score = BigDecimal.valueOf(score).add(chosenOption.getScore()).doubleValue();
                    redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "SCORE", score);
                } else {
                    nextQuestion = ivrTaskTemplateScriptVO.getNextScriptno();
                    //更新分数
                    Object obj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
                    Double score = (obj == null ? new Double(0.00) : new Double(((Double) obj).doubleValue()));
                    score = BigDecimal.valueOf(score).add(chosenOption.getScore()).doubleValue();
                    redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "SCORE", score, 120, TimeUnit.MINUTES);
                }
                if (nextQuestion == null || nextQuestion == 0L) {
                    //如果下一题为空,或者为0,则挂机
                    ServiceSubtask ss = new ServiceSubtask();
                    ss.setId(serviceSubtask.getId());
                    ss.setSendstate(6L);
                    ss.setRemark("电话拨打已完成");
                    serviceSubtaskMapper.updateServiceSubtask(ss);
                    //记录状态
                    setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
                    redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
                    redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
                    redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
                    redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "noVoice");
                    //在redis中保存一下结束语,在调用挂电话的方法时删除
                    ServiceTask serviceTask = serviceTaskService.selectServiceTaskByTaskid(serviceSubtask.getTaskid());
                    redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
                    phoneCallBackYQVO.setType("text");
                    phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + serviceTask.getJsy());
                    //将结果写进detail表
                    ServiceSubTaskDetailReq ssdReq = new ServiceSubTaskDetailReq();
                    List<ServiceSubtaskDetail> serviceSubtaskDetailList2 = new ArrayList<>();
                    serviceSubtaskDetailList.add(getServiceSubtaskDetail(phoneCallReqYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate));
                    serviceSubTaskDetailReq.setServiceSubtaskDetailList(serviceSubtaskDetailList2);
                    ssdReq.setGuid(phoneCallReqYQVO.getGuid());
                    ssdReq.setOrgid(phoneCallReqYQVO.getOrgid());
                    saveQuestionAnswerPhone(ssdReq);
                    return phoneCallBackYQVO;
                }
                for (IvrTaskTemplateScript script : ivrTaskTemplateScripts) {
                    if (script.getSort() == nextQuestion.intValue()) {
                        phoneCallBackYQVO.setType("text");
                        phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
                        String scriptContent = StringUtils.isNotEmpty(script.getIvrtext()) ? script.getIvrtext() : script.getScriptContent();
                        log.error("下一题问题:{}", scriptContent);
                        log.error("下一题的子任务是:{}", serviceSubtask);
                        phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + getObject(serviceSubtask, scriptContent));
                        //将该患者的Redis中的题目ID,进行修改
                        redisCache.setCacheObject(phoneCallReqYQVO.getTaskid().trim() + "-" + phoneCallReqYQVO.getPhone().trim(), script.getId().toString(), 120, TimeUnit.MINUTES);
                        //删除无响应
                        redisCache.deleteObject(phoneCallReqYQVO.getTaskid().trim() + "&&" + "mate" + "&&" + phoneCallReqYQVO.getUuid());
                    }
                }
            } else if (ivrTaskTemplateScriptVO.getNextScriptno() == null || ivrTaskTemplateScriptVO.getNextScriptno() == 0) {
                ServiceTask serviceTask1 = serviceTaskService.selectServiceTaskByTaskid(serviceSubtask.getTaskid());
                phoneCallBackYQVO.setType("text");
                phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
                //更新一下分数
                double score = 0.0;
                Object scoreObj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
                if (ObjectUtils.isNotEmpty(scoreObj)) score = (double) scoreObj;
                serviceSubtask.setScore(BigDecimal.valueOf(score));
                serviceSubtask.setFinishtime(new Date());
                serviceSubtask.setSendstate(6L);
                serviceSubtask.setRemark("电话拨打已完成");
                serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
                //记录状态
                setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
                //设置结束语
                phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + serviceTask1.getJsy());
                Long id = serviceSubtask.getId();
                Map<String, String> map = delRedisValue(null, id.toString());
                log.error("map的值为:{}", map);
                if (ObjectUtils.isNotEmpty(map))
                    redisCache.setCacheObject(map.get("cacheName"), map.get("val"));
                redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
                redisCache.deleteObject(phoneCallReqYQVO.getTaskid().trim() + "&&" + "mate" + "&&" + phoneCallReqYQVO.getUuid());
                redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
                redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
                //在redis中保存一下结束语,在调用挂电话的方法时删除
                ServiceTask serviceTask = serviceTaskService.selectServiceTaskByTaskid(serviceSubtask.getTaskid());
                redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
//                                return phoneCallBackYQVO;
            }
        } else {
            log.info("没有匹配上----------------------------");
            //flag=0,说明没 åŒ¹é…ä¸Šï¼Œä¹Ÿè¦æŠŠæ‚£è€…说的话记录下来
            if (matched == ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().size() - 1 && flag == 0) {
                ServiceSubTaskDetailReq serviceSubTaskDetailReq = new ServiceSubTaskDetailReq();
                List<ServiceSubtaskDetail> serviceSubtaskDetailList = new ArrayList<>();
                ServiceSubtaskDetail serviceSubtaskDetail = getServiceSubtaskDetail(phoneCallReqYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate);
                //修改一下语音路径(改成前端可以访问的,存到数据库中)
                if (StringUtils.isNotEmpty(serviceSubtaskDetail.getQuestionvoice())) {
                    String questionvoice = serviceSubtaskDetail.getQuestionvoice();
                    String[] split = questionvoice.split("\\\\");
                    if (split.length > 0) {
                        String lastPart = split[split.length - 1];
                        serviceSubtaskDetail.setQuestionvoice(voicePathPrefix + lastPart);
                    }
                }
                serviceSubtaskDetailList.add(serviceSubtaskDetail);
                //如果没有 åŒ¹é…ä¸Šï¼Œè¿™ä¸ªå¿…须为null
                serviceSubtaskDetailList.get(0).setMatchedtext("");
                serviceSubTaskDetailReq.setServiceSubtaskDetailList(serviceSubtaskDetailList);
                serviceSubTaskDetailReq.setGuid(phoneCallReqYQVO.getGuid());
                serviceSubTaskDetailReq.setOrgid(phoneCallReqYQVO.getOrgid());
                saveQuestionAnswerPhone(serviceSubTaskDetailReq);
            }
        }
        return back;
    }
    @Test
    public void TestMatch(){
        String questionText = "您好,请问您是患者本人还是家属?\n";
        String voiceText = "我自己";
        String matchedText = "";
        List<IvrTaskTemplateTargetoption> options = new ArrayList<>();
        IvrTaskTemplateTargetoption ivrTaskTemplateTargetoption1 = new IvrTaskTemplateTargetoption();
        ivrTaskTemplateTargetoption1.setTargetvalue("本人");
        options.add(ivrTaskTemplateTargetoption1);
        IvrTaskTemplateTargetoption ivrTaskTemplateTargetoption2 = new IvrTaskTemplateTargetoption();
        ivrTaskTemplateTargetoption2.setTargetvalue("家属");
        options.add(ivrTaskTemplateTargetoption2);
        IvrTaskTemplateTargetoption ivrTaskTemplateTargetoption3 = new IvrTaskTemplateTargetoption();
        ivrTaskTemplateTargetoption3.setTargetvalue("其他");
        options.add(ivrTaskTemplateTargetoption3);
        Integer matched = matchOptionIndex(questionText,voiceText,options);
        if(ObjectUtils.isNotEmpty(matched)){
            if(matched >= 0){
                matchedText = options.get(matched).getTargetvalue();
            }
        }
        log.info("ai匹配成功,匹配结果是:" + matchedText);
    }
}
smartor/src/main/java/com/smartor/service/impl/ServiceTaskServiceImpl.java
@@ -456,6 +456,7 @@
            serviceSubtaskVO.setPatid(patid);
        }
        List<ServiceSubtask> serviceSubtaskList = serviceSubtaskMapper.selectServiceSubtaskList(serviceSubtaskVO);
        List<SvyTaskTemplateScriptVO> svyTaskTemplateScriptVOS = null;
        if (CollectionUtils.isNotEmpty(serviceSubtaskList) && serviceSubtaskList.size() == 1) {
            if (serviceSubtaskList.get(0).getSendstate() == 3 && isFinish == true) {
                ServiceSubtask serviceSubtask = new ServiceSubtask();
@@ -464,22 +465,25 @@
                serviceSubtask.setTaskid(serviceTask.getTaskid());
                serviceSubtaskMapper.updateServiceSubtaskByPatId(serviceSubtask);
            }
        }
        //通过模板ID获取问题信息
        SvyTaskTemplateScript svyTaskTemplateScript = new SvyTaskTemplateScript();
        svyTaskTemplateScript.setTemplateID(Long.valueOf(serviceTask.getTemplateid()));
        if (serviceTask.getTemplateid() != null) svyTaskTemplateScript.setTemplateID(serviceTask.getTemplateid());
        svyTaskTemplateScript.setDelFlag("0");
        List<SvyTaskTemplateScript> svyTaskTemplateScripts = svyTaskTemplateScriptMapper.selectSvyTaskTemplateScriptList(svyTaskTemplateScript);
        if (CollectionUtils.isEmpty(svyTaskTemplateScripts) || svyTaskTemplateScripts.size() == 0) {
            insertSvyTaskTempScript(null, serviceTask);
            svyTaskTemplateScripts = svyTaskTemplateScriptMapper.selectSvyTaskTemplateScriptList(svyTaskTemplateScript);
            if (CollectionUtils.isEmpty(svyTaskTemplateScripts)) {
                throw new BaseException("请联系管理员,检查问题模板信息!");
            }
        }
        List<SvyTaskTemplateScriptVO> svyTaskTemplateScriptVOS = DtoConversionUtils.sourceToTarget(svyTaskTemplateScripts, SvyTaskTemplateScriptVO.class);
            //通过模板ID获取问题信息
            SvyTaskTemplateScript svyTaskTemplateScript = new SvyTaskTemplateScript();
            svyTaskTemplateScript.setTemplateID(Long.valueOf(serviceTask.getTemplateid()));
            if (serviceSubtaskList.get(0).getTemplateid() != null)
                svyTaskTemplateScript.setTemplateID(serviceSubtaskList.get(0).getTemplateid());
            else if (serviceTask.getTemplateid() != null)
                svyTaskTemplateScript.setTemplateID(serviceTask.getTemplateid());
            svyTaskTemplateScript.setDelFlag("0");
            List<SvyTaskTemplateScript> svyTaskTemplateScripts = svyTaskTemplateScriptMapper.selectSvyTaskTemplateScriptList(svyTaskTemplateScript);
            if (CollectionUtils.isEmpty(svyTaskTemplateScripts) || svyTaskTemplateScripts.size() == 0) {
                insertSvyTaskTempScript(null, serviceTask);
                svyTaskTemplateScripts = svyTaskTemplateScriptMapper.selectSvyTaskTemplateScriptList(svyTaskTemplateScript);
                if (CollectionUtils.isEmpty(svyTaskTemplateScripts)) {
                    throw new BaseException("请联系管理员,检查问题模板信息!");
                }
            }
            svyTaskTemplateScriptVOS = DtoConversionUtils.sourceToTarget(svyTaskTemplateScripts, SvyTaskTemplateScriptVO.class);
        }
        //获取患者信息
        PatArchive patArchive = null;
        if (patfrom.equals("0")) patArchive = patArchiveMapper.selectPatArchiveByPatid(patid);
smartor/src/main/resources/mapper/smartor/IvrLibaTemplateScriptMapper.xml
@@ -55,13 +55,20 @@
        <result property="reportDeptName" column="report_dept_code"/>
        <result property="isMydException" column="is_myd_exception"/>
        <result property="dimension" column="dimension"/>
        <result property="dutyDeptPersonName" column="duty_dept_person_name"/>
        <result property="dutyDeptPersonCode" column="duty_dept_person_code"/>
        <result property="reportDeptPersonCode" column="report_dept_person_name"/>
        <result property="reportDeptPersonName" column="report_dept_person_code"/>
    </resultMap>
    <sql id="selectIvrLibaTemplateScriptVo">
        select id,
               scriptno,
               is_myd_exception,
               duty_dept_person_name,
               duty_dept_person_code,
               report_dept_person_name,
               report_dept_person_code,
               dimension,
               sort,
               script_assortname,
@@ -174,6 +181,18 @@
        <if test="scriptType != null">and script_type = #{scriptType}</if>
        <if test="sort != null">and sort = #{sort}</if>
        <if test="score != null">and score = #{score}</if>
        <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">and duty_dept_person_name like concat('%', #{dutyDeptPersonName},
            '%')
        </if>
        <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">and duty_dept_person_code like concat('%', #{dutyDeptPersonCode},
            '%')
        </if>
        <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">and report_dept_person_name like concat('%', #{reportDeptPersonName},
            '%')
        </if>
        <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">and report_dept_person_code like concat('%', #{reportDeptPersonCode},
            '%')
        </if>
    </select>
@@ -187,6 +206,18 @@
                </foreach>
            </if>
            <if test="dimensionList == null ">and dimension IS NOT NULL </if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">and duty_dept_person_name like concat('%', #{dutyDeptPersonName},
                '%')
            </if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">and duty_dept_person_code like concat('%', #{dutyDeptPersonCode},
                '%')
            </if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">and report_dept_person_name like concat('%', #{reportDeptPersonName},
                '%')
            </if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">and report_dept_person_code like concat('%', #{reportDeptPersonCode},
                '%')
            </if>
        </where>
    </select>
@@ -248,6 +279,10 @@
            <if test="reportDeptCode != null  and reportDeptCode != ''">report_dept_code,</if>
            <if test="isMydException != null  and isMydException != ''">is_myd_exception,</if>
            <if test="dimension != null  and dimension != ''">dimension,</if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">duty_dept_person_name,</if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">duty_dept_person_code,</if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">report_dept_person_name,</if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">report_dept_person_code,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="scriptno != null">#{scriptno},</if>
@@ -298,6 +333,10 @@
            <if test="reportDeptCode != null  and reportDeptCode != ''">#{reportDeptCode},</if>
            <if test="isMydException != null  and isMydException != ''">#{isMydException},</if>
            <if test="dimension != null  and dimension != ''">#{dimension},</if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">#{dutyDeptPersonName},</if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">#{dutyDeptPersonCode},</if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">#{reportDeptPersonName},</if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">#{reportDeptPersonCode},</if>
        </trim>
    </insert>
@@ -331,6 +370,10 @@
            <if test="orgid != null">orgid = #{orgid},</if>
            <if test="pid != null">pid = #{pid},</if>
            <if test="guid != null">guid = #{guid},</if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">duty_dept_person_name = #{dutyDeptPersonName},</if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">duty_dept_person_code = #{dutyDeptPersonCode},</if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">report_dept_person_name = #{reportDeptPersonName},</if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">report_dept_person_code = #{reportDeptPersonCode},</if>
            <if test="targetid != null">targetid = #{targetid},</if>
            <if test="scriptTopic != null">script_topic = #{scriptTopic},</if>
            <if test="nextScriptno != null">next_scriptno = #{nextScriptno},</if>
smartor/src/main/resources/mapper/smartor/IvrTaskTemplateScriptMapper.xml
@@ -55,6 +55,10 @@
        <result property="reportDeptName" column="report_dept_code"/>
        <result property="dimension" column="dimension"/>
        <result property="isMydException" column="is_myd_exception"/>
        <result property="dutyDeptPersonName" column="duty_dept_person_name"/>
        <result property="dutyDeptPersonCode" column="duty_dept_person_code"/>
        <result property="reportDeptPersonCode" column="report_dept_person_name"/>
        <result property="reportDeptPersonName" column="report_dept_person_code"/>
    </resultMap>
    <sql id="selectIvrTaskTemplateScriptVo">
@@ -67,6 +71,10 @@
               report_dept_name,
               report_dept_code,
               script_assortid,
               duty_dept_person_name,
               duty_dept_person_code,
               report_dept_person_name,
               report_dept_person_code,
               sort,
               ivrtext,
               script_type,
@@ -154,6 +162,22 @@
        <if test="branchNextscriptno != null  and branchNextscriptno != ''">and branch_nextscriptno =
            #{branchNextscriptno}
        </if>
        <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">and duty_dept_person_name like concat('%',
            #{dutyDeptPersonName},
            '%')
        </if>
        <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">and duty_dept_person_code like concat('%',
            #{dutyDeptPersonCode},
            '%')
        </if>
        <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">and report_dept_person_name like concat('%',
            #{reportDeptPersonName},
            '%')
        </if>
        <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">and report_dept_person_code like concat('%',
            #{reportDeptPersonCode},
            '%')
        </if>
    </select>
    <select id="selectIvrTaskTemplateScriptByID" parameterType="Long" resultMap="IvrTaskTemplateScriptResult">
@@ -213,6 +237,10 @@
            <if test="reportDeptCode != null  and reportDeptCode != ''">report_dept_code,</if>
            <if test="dimension != null  and dimension != ''">dimension,</if>
            <if test="isMydException != null  and isMydException != ''">is_myd_exception,</if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">duty_dept_person_name,</if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">duty_dept_person_code,</if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">report_dept_person_name,</if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">report_dept_person_code,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="taskid != null">#{taskid},</if>
@@ -263,6 +291,10 @@
            <if test="reportDeptCode != null  and reportDeptCode != ''">#{reportDeptCode},</if>
            <if test="dimension != null  and dimension != ''">#{dimension},</if>
            <if test="isMydException != null  and isMydException != ''">#{isMydException},</if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">#{dutyDeptPersonName},</if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">#{dutyDeptPersonCode},</if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">#{reportDeptPersonName},</if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">#{reportDeptPersonCode},</if>
        </trim>
    </insert>
@@ -319,6 +351,10 @@
            <if test="dutyDeptCode != null  and dutyDeptCode != ''">duty_dept_code = #{dutyDeptCode},</if>
            <if test="reportDeptName != null  and reportDeptName != ''">report_dept_name = #{reportDeptName},</if>
            <if test="reportDeptCode != null  and reportDeptCode != ''">report_dept_code = #{reportDeptCode},</if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">duty_dept_person_name = #{dutyDeptPersonName},</if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">duty_dept_person_code = #{dutyDeptPersonCode},</if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">report_dept_person_name = #{reportDeptPersonName},</if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">report_dept_person_code = #{reportDeptPersonCode},</if>
        </trim>
        where id = #{id}
    </update>
smartor/src/main/resources/mapper/smartor/PatArchiveMapper.xml
@@ -189,7 +189,6 @@
            <if test="idcardno != null  and idcardno != ''">and idcardno = #{idcardno}</if>
            <if test="sourcefrom != null ">and sourcefrom = #{sourcefrom}</if>
            <if test="telcode != null  and telcode != ''">and telcode = #{telcode}</if>
            <if test="orgid != null  and orgid != ''">and orgid = #{orgid}</if>
            <if test="id != null  and id != ''">and id = #{id}</if>
            <if test="isupload != null ">and isupload = #{isupload}</if>
            <if test="uploadTime != null ">and upload_time = #{uploadTime}</if>
@@ -214,7 +213,7 @@
            <if test="casePersonAge != null ">and case_person_age = #{casePersonAge}</if>
            <if test="filterDrname != null ">and filter_drname = #{filterDrname}</if>
            <if test="filterDrcode != null ">and filter_drcode = #{filterDrcode}</if>
            <if test="campusid != null ">and campusid = #{campusid}</if>
        <if test="pageSize != null  and pageNum != null">limit ${pageSize} OFFSET ${pageNum}</if>
    </select>
@@ -932,10 +931,9 @@
        d.leavehospitaldistrictcode AS leavehospitaldistrictcode
        FROM
        pat_med_inhosp d
        JOIN pat_archive a ON a.id = d.patid
        LEFT JOIN pat_archive a ON a.id = d.patid
        where 1=1
            and d.del_flag != 1
            AND a.del_flag != 1
            and d.orgid = #{orgid}
            <if test="name != null  and name != ''">and a.name like concat('%', #{name}, '%')</if>
            <if test="idcardno != null  and idcardno != ''">and a.idcardno = #{idcardno}</if>
@@ -1005,7 +1003,7 @@
            </if>
            <if test="pids != null">
                AND a.id NOT IN
                AND d.patid NOT IN
                <foreach collection="pids" item="pid" open="(" separator="," close=")">
                    #{pid}
                </foreach>
@@ -1201,12 +1199,10 @@
    <!-- ä½é™¢æ‚£è€…总数统计(去重) -->
    <select id="countPatArchiveInfoByInhospQC" parameterType="com.smartor.domain.PatArchiveReq" resultType="long">
        SELECT COUNT(DISTINCT a.id)
        SELECT COUNT(DISTINCT d.patid)
        FROM pat_med_inhosp d
        JOIN pat_archive a ON a.id = d.patid
        WHERE 1=1
            AND d.del_flag != 1
            AND a.del_flag != 1
            AND d.orgid = #{orgid}
            <if test="name != null  and name != ''">AND a.name like concat('%', #{name}, '%')</if>
            <if test="idcardno != null  and idcardno != ''">AND a.idcardno = #{idcardno}</if>
@@ -1250,7 +1246,7 @@
                </foreach>
            </if>
            <if test="pids != null">
                AND a.id NOT IN
                AND d.patid NOT IN
                <foreach collection="pids" item="pid" open="(" separator="," close=")">
                    #{pid}
                </foreach>
smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailTraceMapper.xml
@@ -55,10 +55,18 @@
        <result property="templateType" column="template_type"/>
        <result property="isMydException" column="is_myd_exception"/>
        <result property="dimension" column="dimension"/>
        <result property="dutyDeptPersonName" column="duty_dept_person_name"/>
        <result property="dutyDeptPersonCode" column="duty_dept_person_code"/>
        <result property="reportDeptPersonCode" column="report_dept_person_name"/>
        <result property="reportDeptPersonName" column="report_dept_person_code"/>
    </resultMap>
    <sql id="selectServiceSubtaskDetailTtraceVo">
        select id,
               duty_dept_person_name,
               duty_dept_person_code,
               report_dept_person_name,
               report_dept_person_code,
               detail_id,
               is_myd_exception,
               dimension,
@@ -257,6 +265,19 @@
        <if test="isMydException != null ">
            and is_myd_exception = #{isMydException}
        </if>
        <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">
            and duty_dept_person_name like concat('%', #{dutyDeptPersonName}, '%')
        </if>
        <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">
            and duty_dept_person_code like concat('%', #{dutyDeptPersonCode}, '%')
        </if>
        <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">
            and report_dept_person_name like concat('%', #{reportDeptPersonName}, '%')
        </if>
        <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">
            and report_dept_person_code like concat('%', #{reportDeptPersonCode}, '%')
        </if>
        <if test="pageSize != null  and pageNum != null">limit ${pageSize} OFFSET ${pageNum}</if>
    </select>
    <select id="tracedeallist" parameterType="com.smartor.domain.VO.DetailTraceDealVO"
@@ -292,6 +313,18 @@
        </if>
        <if test="dimension != null  and dimension != ''">
            and dimension = #{dimension}
        </if>
        <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">
            and duty_dept_person_name like concat('%', #{dutyDeptPersonName}, '%')
        </if>
        <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">
            and duty_dept_person_code like concat('%', #{dutyDeptPersonCode}, '%')
        </if>
        <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">
            and report_dept_person_name like concat('%', #{reportDeptPersonName}, '%')
        </if>
        <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">
            and report_dept_person_code like concat('%', #{reportDeptPersonCode}, '%')
        </if>
    </select>
@@ -406,6 +439,14 @@
            </if>
            <if test="isMydException != null">is_myd_exception,
            </if>
            <if test="dutyDeptPersonName != null">duty_dept_person_name,
            </if>
            <if test="dutyDeptPersonCode != null">duty_dept_person_code,
            </if>
            <if test="reportDeptPersonName != null">report_dept_person_name,
            </if>
            <if test="reportDeptPersonCode != null">report_dept_person_code,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="detailId != null">#{detailId},
@@ -507,6 +548,14 @@
            <if test="dimension != null">#{dimension},
            </if>
            <if test="isMydException != null">#{isMydException},
            </if>
            <if test="dutyDeptPersonName != null">#{dutyDeptPersonName},
            </if>
            <if test="dutyDeptPersonCode != null">#{dutyDeptPersonCode},
            </if>
            <if test="reportDeptPersonName != null">#{reportDeptPersonName},
            </if>
            <if test="reportDeptPersonCode != null">#{reportDeptPersonCode},
            </if>
        </trim>
    </insert>
@@ -664,6 +713,18 @@
            <if test="isMydException != null">is_myd_exception =
                #{isMydException},
            </if>
            <if test="dutyDeptPersonName != null">duty_dept_person_name =
                #{dutyDeptPersonName},
            </if>
            <if test="dutyDeptPersonCode != null">duty_dept_person_code =
                #{dutyDeptPersonCode},
            </if>
            <if test="reportDeptPersonName != null">report_dept_person_name =
                #{reportDeptPersonName},
            </if>
            <if test="reportDeptPersonCode != null">report_dept_person_code =
                #{reportDeptPersonCode},
            </if>
        </trim>
        where id = #{id}
    </update>
smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
@@ -486,6 +486,7 @@
        <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="campusid != null  and campusid != ''">and campusid = #{campusid}</if>
        <if test="pid != null ">and pid = #{pid}</if>
        <if test="preachform != null ">and preachform = #{preachform}</if>
        <if test="currentPreachform != null ">and current_preachform = #{currentPreachform}</if>
@@ -2525,7 +2526,8 @@
        SUM(CASE WHEN sendstate = 1 THEN 1 ELSE 0 END) AS blq,
        SUM(CASE WHEN sendstate = 4 THEN 1 ELSE 0 END) AS wxsf,
        SUM(CASE WHEN sendstate != 4 THEN 1 ELSE 0 END) AS xsf,
        SUM(CASE WHEN (sendstate = 1 OR sendstate = 2 OR sendstate = 3 OR sendstate = 5 OR sendstate = 7 ) THEN 1 ELSE 0 END) AS dsf,
        SUM(CASE WHEN (sendstate = 1 OR sendstate = 2 OR sendstate = 3 OR sendstate = 5 OR sendstate = 7 ) THEN 1 ELSE 0
        END) AS dsf,
        SUM(CASE WHEN sendstate = 6 THEN 1 ELSE 0 END) AS ywc,
        SUM(CASE WHEN excep IS NOT NULL AND excep = '1' THEN 1 ELSE 0 END) AS yc,
        SUM(CASE WHEN excep IS NOT NULL AND excep = '2' THEN 1 ELSE 0 END) AS jg,
@@ -2689,6 +2691,9 @@
        <if test="orgid != null and orgid != ''">
            AND orgid = #{orgid}
        </if>
        <if test="campusid != null and campusid != ''">
            AND campusid = #{campusid}
        </if>
        <if test="guid != null and guid != ''">
            AND guid = #{guid}
        </if>
smartor/src/main/resources/mapper/smartor/SvyLibTemplateScriptMapper.xml
@@ -50,6 +50,10 @@
        <result property="dutyDeptCode" column="duty_dept_code"/>
        <result property="reportDeptCode" column="report_dept_name"/>
        <result property="reportDeptName" column="report_dept_code"/>
        <result property="dutyDeptPersonName" column="duty_dept_person_name"/>
        <result property="dutyDeptPersonCode" column="duty_dept_person_code"/>
        <result property="reportDeptPersonCode" column="report_dept_person_name"/>
        <result property="reportDeptPersonName" column="report_dept_person_code"/>
        <result property="isMydException" column="is_myd_exception"/>
        <result property="dimension" column="dimension"/>
@@ -64,6 +68,10 @@
               duty_dept_code,
               report_dept_name,
               report_dept_code,
               duty_dept_person_name,
               duty_dept_person_code,
               report_dept_person_name,
               report_dept_person_code,
               targetid,
               group_name,
               targetname,
@@ -168,6 +176,22 @@
                #{categoryid}
            </foreach>
        </if>
        <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">and duty_dept_person_name like concat('%',
            #{dutyDeptPersonName},
            '%')
        </if>
        <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">and duty_dept_person_code like concat('%',
            #{dutyDeptPersonCode},
            '%')
        </if>
        <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">and report_dept_person_name like concat('%',
            #{reportDeptPersonName},
            '%')
        </if>
        <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">and report_dept_person_code like concat('%',
            #{reportDeptPersonCode},
            '%')
        </if>
        <if test="pageSize != null  and pageNum != null">limit ${pageSize} OFFSET ${pageNum}</if>
    </select>
@@ -179,6 +203,22 @@
                <foreach item="dimension" collection="dimensionList" open="(" separator="," close=")">
                    #{dimension}
                </foreach>
            </if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">and duty_dept_person_name like concat('%',
                #{dutyDeptPersonName},
                '%')
            </if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">and duty_dept_person_code like concat('%',
                #{dutyDeptPersonCode},
                '%')
            </if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">and report_dept_person_name like concat('%',
                #{reportDeptPersonName},
                '%')
            </if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">and report_dept_person_code like concat('%',
                #{reportDeptPersonCode},
                '%')
            </if>
            <if test="dimensionList == null ">and dimension IS NOT NULL </if>
        </where>
@@ -240,6 +280,10 @@
            <if test="categoryName != null  and categoryName != ''">categoryName,</if>
            <if test="isMydException != null  and isMydException != ''">is_myd_exception,</if>
            <if test="dimension != null  and dimension != ''">dimension,</if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">duty_dept_person_name,</if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">duty_dept_person_code,</if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">report_dept_person_name,</if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">report_dept_person_code,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="nextScriptno != null">#{nextScriptno},</if>
@@ -289,6 +333,10 @@
            <if test="categoryName != null  and categoryName != ''">#{categoryName},</if>
            <if test="isMydException != null  and isMydException != ''">#{isMydException},</if>
            <if test="dimension != null  and dimension != ''">#{dimension},</if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">#{dutyDeptPersonName},</if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">#{dutyDeptPersonCode},</if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">#{reportDeptPersonName},</if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">#{reportDeptPersonCode},</if>
        </trim>
    </insert>
@@ -344,6 +392,10 @@
            <if test="categoryName != null  and categoryName != ''">categoryName = #{categoryName},</if>
            <if test="isMydException != null  and isMydException != ''">is_myd_exception = #{isMydException},</if>
            <if test="dimension != null  and dimension != ''">dimension = #{dimension},</if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">duty_dept_person_name = #{dutyDeptPersonName},</if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">duty_dept_person_code = #{dutyDeptPersonCode},</if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">report_dept_person_name = #{reportDeptPersonName},</if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">report_dept_person_code = #{reportDeptPersonCode},</if>
        </trim>
        where id = #{id}
    </update>
smartor/src/main/resources/mapper/smartor/SvyTaskTemplateMapper.xml
@@ -93,45 +93,45 @@
            resultMap="SvyTaskTemplateResult">
        <include refid="selectSvyTaskTemplateVo"/>
        where 1=1
            and del_flag = 0
            <if test="templateid != null ">and templateid = #{templateid}</if>
            <if test="id != null ">and id = #{id}</if>
            <if test="categoryid != null ">and categoryid = #{categoryid}</if>
            <if test="svycode != null  and svycode != ''">and svycode = #{svycode}</if>
            <if test="svyname != null  and svyname != ''">and svyname like concat('%', #{svyname}, '%')</if>
            <if test="description != null  and description != ''">and description = #{description}</if>
            <if test="introduce != null  and introduce != ''">and introduce = #{introduce}</if>
            <if test="submitprompt != null  and submitprompt != ''">and submitprompt = #{submitprompt}</if>
            <if test="tag != null  and tag != ''">and tag = #{tag}</if>
            <if test="version != null ">and version = #{version}</if>
            <if test="centerlibrarycode != null  and centerlibrarycode != ''">and centerlibrarycode =
                #{centerlibrarycode}
            </if>
            <if test="centerlibraryid != null ">and centerlibraryid = #{centerlibraryid}</if>
            <if test="islocal != null ">and islocal = #{islocal}</if>
            <if test="isenable != null  and isenable != ''">and isenable = #{isenable}</if>
            <if test="orgid != null  and orgid != ''">and orgid = #{orgid}</if>
            <if test="isupload != null ">and isupload = #{isupload}</if>
            <if test="uploadTime != null ">and upload_time = #{uploadTime}</if>
            <if test="taskScriptId != null  and taskScriptId != ''">and task_script_id = #{taskScriptId}</if>
            <if test="pid != null ">and pid = #{pid}</if>
            <if test="guid != null  and guid != ''">and guid = #{guid}</if>
            <if test="deptNames != null  and deptNames != ''">and dept_names = #{deptNames}</if>
            <if test="labelInfo != null  and labelInfo != ''">and label_info = #{labelInfo}</if>
            <if test="campus != null  and campus != ''">and campus = #{campus}</if>
            <if test="suitway != null  and suitway != ''">and suitway = #{suitway}</if>
            <if test="otherdata != null  and otherdata != ''">and otherdata = #{otherdata}</if>
            <if test="valueType != null  and valueType != ''">and value_type = #{valueType}</if>
            <if test="reply != null  and reply != ''">and reply = #{reply}</if>
            <if test="taskid != null ">and taskid = #{taskid}</if>
            <if test="deptCode != null ">and dept_code = #{deptCode}</if>
            <if test="longTemp != null ">and long_temp = #{longTemp}</if>
            <if test="sendDay != null ">and send_day = #{sendDay}</if>
        and del_flag = 0
        <if test="templateid != null ">and templateid = #{templateid}</if>
        <if test="id != null ">and id = #{id}</if>
        <if test="categoryid != null ">and categoryid = #{categoryid}</if>
        <if test="svycode != null  and svycode != ''">and svycode = #{svycode}</if>
        <if test="svyname != null  and svyname != ''">and svyname like concat('%', #{svyname}, '%')</if>
        <if test="description != null  and description != ''">and description = #{description}</if>
        <if test="introduce != null  and introduce != ''">and introduce = #{introduce}</if>
        <if test="submitprompt != null  and submitprompt != ''">and submitprompt = #{submitprompt}</if>
        <if test="tag != null  and tag != ''">and tag = #{tag}</if>
        <if test="version != null ">and version = #{version}</if>
        <if test="centerlibrarycode != null  and centerlibrarycode != ''">and centerlibrarycode =
            #{centerlibrarycode}
        </if>
        <if test="centerlibraryid != null ">and centerlibraryid = #{centerlibraryid}</if>
        <if test="islocal != null ">and islocal = #{islocal}</if>
        <if test="isenable != null  and isenable != ''">and isenable = #{isenable}</if>
        <if test="orgid != null  and orgid != ''">and orgid = #{orgid}</if>
        <if test="isupload != null ">and isupload = #{isupload}</if>
        <if test="uploadTime != null ">and upload_time = #{uploadTime}</if>
        <if test="taskScriptId != null  and taskScriptId != ''">and task_script_id = #{taskScriptId}</if>
        <if test="pid != null ">and pid = #{pid}</if>
        <if test="guid != null  and guid != ''">and guid = #{guid}</if>
        <if test="deptNames != null  and deptNames != ''">and dept_names = #{deptNames}</if>
        <if test="labelInfo != null  and labelInfo != ''">and label_info = #{labelInfo}</if>
        <if test="campus != null  and campus != ''">and campus = #{campus}</if>
        <if test="suitway != null  and suitway != ''">and suitway = #{suitway}</if>
        <if test="otherdata != null  and otherdata != ''">and otherdata = #{otherdata}</if>
        <if test="valueType != null  and valueType != ''">and value_type = #{valueType}</if>
        <if test="reply != null  and reply != ''">and reply = #{reply}</if>
        <if test="taskid != null ">and taskid = #{taskid}</if>
        <if test="deptCode != null ">and dept_code = #{deptCode}</if>
        <if test="longTemp != null ">and long_temp = #{longTemp}</if>
        <if test="sendDay != null ">and send_day = #{sendDay}</if>
    </select>
    <select id="selectSvyTaskTemplateBySvyid" parameterType="Long" resultMap="SvyTaskTemplateResult">
        <include refid="selectSvyTaskTemplateVo"/>
        where del_flag=0 and  id = #{id}
        where del_flag=0 and id = #{id}
    </select>
    <insert id="insertSvyTaskTemplate" parameterType="com.smartor.domain.SvyTaskTemplate" useGeneratedKeys="true"
@@ -265,8 +265,8 @@
    </update>
    <delete id="deleteSvyTaskTemplateBySvyid" parameterType="Long">
        delete
        from svy_task_template
        update svy_task_template
        set del_flag=1
        where id = #{id}
    </delete>
smartor/src/main/resources/mapper/smartor/SvyTaskTemplateScriptMapper.xml
@@ -49,6 +49,10 @@
        <result property="dutyDeptCode" column="duty_dept_code"/>
        <result property="reportDeptCode" column="report_dept_name"/>
        <result property="reportDeptName" column="report_dept_code"/>
        <result property="dutyDeptPersonName" column="duty_dept_person_name"/>
        <result property="dutyDeptPersonCode" column="duty_dept_person_code"/>
        <result property="reportDeptPersonCode" column="report_dept_person_name"/>
        <result property="reportDeptPersonName" column="report_dept_person_code"/>
        <result property="isMydException" column="is_myd_exception"/>
        <result property="dimension" column="dimension"/>
    </resultMap>
@@ -77,6 +81,7 @@
               templateID,
               scriptid,
               script_topic, language, categoryName, script_content, is_must, del_flag, update_by, update_time, create_by, create_time, isupload, upload_time, orgid, pid, guid, value_type, targetoptions, script_type, targetid, targetvalue, next_scriptno, script_result, otherdata, picture_path
                , duty_dept_person_name, duty_dept_person_code, report_dept_person_name, report_dept_person_code
        from svy_task_template_script
    </sql>
@@ -135,6 +140,18 @@
            <if test="branchNextscriptno != null  and branchNextscriptno != ''">and branch_nextscriptno =
                #{branchNextscriptno}
            </if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">and duty_dept_person_name like concat('%', #{dutyDeptPersonName},
                '%')
            </if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">and duty_dept_person_code like concat('%', #{dutyDeptPersonCode},
                '%')
            </if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">and report_dept_person_name like concat('%', #{reportDeptPersonName},
                '%')
            </if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">and report_dept_person_code like concat('%', #{reportDeptPersonCode},
                '%')
            </if>
    </select>
    <select id="selectSvyTaskTemplateScriptByID" parameterType="Long" resultMap="SvyTaskTemplateScriptResult">
@@ -191,6 +208,10 @@
            <if test="reportDeptCode != null  and reportDeptCode != ''"> report_dept_code,</if>
            <if test="isMydException != null ">is_myd_exception,</if>
            <if test="dimension != null ">dimension,</if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">duty_dept_person_name,</if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">duty_dept_person_code,</if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">report_dept_person_name,</if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">report_dept_person_code,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="taskid != null">#{taskid},</if>
@@ -238,6 +259,10 @@
            <if test="reportDeptCode != null  and reportDeptCode != ''">#{reportDeptCode},</if>
            <if test="isMydException != null ">#{isMydException},</if>
            <if test="dimension != null ">#{dimension},</if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">#{dutyDeptPersonName},</if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">#{dutyDeptPersonCode},</if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">#{reportDeptPersonName},</if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">#{reportDeptPersonCode},</if>
        </trim>
    </insert>
@@ -291,6 +316,10 @@
            <if test="reportDeptCode != null  and reportDeptCode != ''">report_dept_code = #{reportDeptCode},</if>
            <if test="isMydException != null ">is_myd_exception = #{isMydException},</if>
            <if test="dimension != null ">dimension = #{dimension},</if>
            <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">duty_dept_person_name = #{dutyDeptPersonName},</if>
            <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">duty_dept_person_code = #{dutyDeptPersonCode},</if>
            <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">report_dept_person_name = #{reportDeptPersonName},</if>
            <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">report_dept_person_code = #{reportDeptPersonCode},</if>
        </trim>
        where id = #{d}
    </update>