From 035108ae9d6ea2c2daa860921f296fda02a8e410 Mon Sep 17 00:00:00 2001
From: liusheng <337615773@qq.com>
Date: 星期三, 02 九月 2026 10:42:25 +0800
Subject: [PATCH] 1.满意度导出BUG处理 2.三汇电话接口部分 3.外链可以通过subid查询到

---
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java                    |  337 +++++++---------
 smartor/src/main/java/com/smartor/service/IServicePhoneService.java                            |   22 +
 smartor/src/main/java/com/smartor/domain/ServiceOutPath.java                                   |   16 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskAnswerController.java |   24 
 smartor/src/main/resources/mapper/smartor/ServiceOutPathMapper.xml                             |   30 +
 smartor/src/main/java/com/smartor/service/IServiceSubtaskService.java                          |   14 
 ruoyi-system/src/main/resources/mapper/system/SmsTempletMapper.xml                             |    1 
 smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml                             |   54 ++
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/SmsTempletController.java           |    7 
 smartor/src/main/java/com/smartor/domain/VO/ServiceSubtaskVO.java                              |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java               |    1 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java       |   12 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java              |    6 
 smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java                  |  233 ++++++++++
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServicePhoneController.java         |   63 +++
 smartor/src/main/java/com/smartor/domain/PhoneCallBackSHVO.java                                |   50 ++
 smartor/src/main/java/com/smartor/domain/PhoneCallResultYQVO.java                              |   74 +++
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java                   |    2 
 smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java                             |   14 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java                 |   16 
 smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskAnswerServiceImpl.java            |   18 
 smartor/src/main/java/com/smartor/service/impl/ServicPhoneServiceImpl.java                     |  200 ++++++++++
 22 files changed, 973 insertions(+), 225 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServicePhoneController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServicePhoneController.java
new file mode 100644
index 0000000..af5416f
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServicePhoneController.java
@@ -0,0 +1,63 @@
+package com.ruoyi.web.controller.smartor;
+
+import com.ruoyi.common.core.controller.BaseController;
+import com.smartor.domain.OutboundConfigAddReqVO;
+import com.smartor.domain.OutboundInstanceResVO;
+import com.smartor.domain.PhoneCallBackSHVO;
+import com.smartor.domain.PhoneCallReqYQVO;
+import com.smartor.domain.PhoneCallResultYQVO;
+import com.smartor.service.IServicePhoneService;
+import com.smartor.service.IServiceSubtaskService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+/**
+ * 涓夋眹鐢佃瘽娴佺▼鏈嶅姟 Controller
+ *
+ * @author ls
+ * @date 2026-08-26
+ */
+@Slf4j
+@Api(description = "涓夋眹鐢佃瘽娴佺▼鏈嶅姟")
+@RestController
+@RequestMapping("/smartor/shphone")
+public class ServicePhoneController extends BaseController {
+    @Autowired
+    private IServiceSubtaskService serviceSubtaskService;
+
+    @Autowired
+    private IServicePhoneService iServicePhoneService;
+
+    @ApiOperation("鏍规嵁鐢佃瘽鍙风爜,鑾峰彇棣栦釜闂")
+    @PostMapping("/getFirstQues")
+    public Map<String, Object> getFirstQues(@RequestBody PhoneCallReqYQVO phoneCallReqYQVO) {
+        log.info("鏍规嵁鐢佃瘽鍙风爜,鑾峰彇棣栦釜闂锛焮}", phoneCallReqYQVO);
+        PhoneCallBackSHVO phoneCallBackSHVO = serviceSubtaskService.getFirstQues(phoneCallReqYQVO);
+        return success(phoneCallBackSHVO);
+    }
+
+    @ApiOperation("涓夋眹 ASR 缁撴灉澶勭悊")
+    @PostMapping("/processResust")
+    public Map<String, Object> processResust(@RequestBody PhoneCallResultYQVO resultYQVO) {
+        log.info("涓夋眹 ASR 缁撴灉澶勭悊 (涓夋眹)锛焮}", resultYQVO);
+        PhoneCallBackSHVO phoneCallBackSHVO = serviceSubtaskService.processResust(resultYQVO);
+        return success(phoneCallBackSHVO);
+    }
+
+    @ApiOperation("鏂板澶栧懠瀹炰緥閰嶇疆")
+    @PostMapping("/addOutboundInstance")
+    public Map<String, Object> addOutboundInstance(@RequestBody OutboundConfigAddReqVO request) {
+        log.info("鏂板澶栧懠瀹炰緥閰嶇疆锛歿}", request);
+        OutboundInstanceResVO outboundInstanceResVO = iServicePhoneService.addOutboundInstance(request);
+        return success(outboundInstanceResVO);
+    }
+
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskAnswerController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskAnswerController.java
index 6f2f428..423e59d 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskAnswerController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskAnswerController.java
@@ -114,11 +114,18 @@
         return toAjax(serviceSubtaskAnswerService.deleteServiceSubtaskAnswerByIds(ids));
     }
 
-    @ApiOperation("鎮h�呴棶棰樼粨鏋滆褰�(澶栭摼)")
+    /**
+     * 鎮h�呴棶棰樼粨鏋滆褰� (澶栭摼) - 寮傛澶勭悊
+     */
+    @ApiOperation("鎮h�呴棶棰樼粨鏋滆褰� (澶栭摼)")
     @PostMapping("/saveQuestionAnswer")
     public AjaxResult saveQuestionAnswer(@RequestBody ServiceSubTaskAnswerReq serviceSubTaskAnswerReq) {
-        log.info("銆恠aveQuestionCache-----saveQuestionAnswer銆戠殑鍏ュ弬涓簆rarm1锛歿},prarm2锛歿},type锛歿},isabnormal:{}", serviceSubTaskAnswerReq.getParam1(), serviceSubTaskAnswerReq.getParam2(), serviceSubTaskAnswerReq.getType(), serviceSubTaskAnswerReq.getIsabnormal());
-        return toAjax(serviceSubtaskAnswerService.saveQuestionAnswer(serviceSubTaskAnswerReq, 0L));
+        log.info("銆恠aveQuestionAnswer銆戠殑鍏ュ弬涓� param1:{},param2:{},type:{},isabnormal:{}", 
+                serviceSubTaskAnswerReq.getParam1(), serviceSubTaskAnswerReq.getParam2(), 
+                serviceSubTaskAnswerReq.getType(), serviceSubTaskAnswerReq.getIsabnormal());
+        // 寮傛澶勭悊淇濆瓨閫昏緫锛岀珛鍗宠繑鍥炴垚鍔熸秷鎭�
+        serviceSubtaskAnswerService.saveQuestionAnswer(serviceSubTaskAnswerReq, 0L);
+        return success("鎻愪氦鎴愬姛锛屾鍦ㄥ鐞嗕腑...");
     }
 
 
@@ -137,11 +144,16 @@
     }
 
 
-    @ApiOperation("鎮h�呴棶棰樼粨鏋滆褰�(灏忕▼鍏呭閾�)")
+    /**
+     * 鎮h�呴棶棰樼粨鏋滆褰� (灏忕▼搴忓閾�) - 寮傛澶勭悊
+     */
+    @ApiOperation("鎮h�呴棶棰樼粨鏋滆褰� (灏忕▼鍏呭閾�)")
     @PostMapping("/saveQuestionAnswerXCH")
     public AjaxResult saveQuestionAnswerXCH(@RequestBody ServiceSubTaskAnswerReq serviceSubTaskAnswerReq) {
-        log.info("銆恠aveQuestionCache-----saveQuestionAnswerXCH銆戠殑鍏ュ弬涓猴細{}", serviceSubTaskAnswerReq);
-        return toAjax(serviceSubtaskAnswerService.saveQuestionAnswer(serviceSubTaskAnswerReq, 1L));
+        log.info("銆恠aveQuestionAnswerXCH銆戠殑鍏ュ弬涓猴細{}", serviceSubTaskAnswerReq);
+        // 寮傛澶勭悊淇濆瓨閫昏緫锛岀珛鍗宠繑鍥炴垚鍔熸秷鎭�
+        serviceSubtaskAnswerService.saveQuestionAnswer(serviceSubTaskAnswerReq, 1L);
+        return success("鎻愪氦鎴愬姛锛屾鍦ㄥ鐞嗕腑...");
     }
 
     @ApiOperation("鑾峰彇鎮h�呴棶棰樼粨鏋滆褰曠紦瀛�(灏忕▼搴忓閾�)")
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java
index 0eeea26..c78d43a 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java
@@ -276,9 +276,15 @@
                 }
             }
 
-            //鑾峰彇serviceSubtaskList涓殑鎵�鏈塼askid
-            List<Long> taskIds = serviceSubtaskList.stream().map(ServiceSubtaskRes::getTaskid).filter(ObjectUtils::isNotEmpty).distinct().collect(Collectors.toList());
-            serviceSubtaskDetailRatioExports = serviceSubtaskService.statQuestionOption(taskIds, serviceSubtaskVO.getStartOutHospTime(), serviceSubtaskVO.getEndOutHospTime());
+            if (StringUtils.isNotEmpty(serviceSubtaskVO.getServiceType()) && serviceSubtaskVO.getServiceType().equals("2")) {
+                //鑾峰彇serviceSubtaskList涓殑鎵�鏈塼askid
+                List<Long> taskIds = serviceSubtaskList.stream().map(ServiceSubtaskRes::getTaskid).filter(ObjectUtils::isNotEmpty).distinct().collect(Collectors.toList());
+                serviceSubtaskDetailRatioExports = serviceSubtaskService.statQuestionOption(taskIds, serviceSubtaskVO.getStartOutHospTime(), serviceSubtaskVO.getEndOutHospTime());
+            } else if (StringUtils.isNotEmpty(serviceSubtaskVO.getServiceType()) && serviceSubtaskVO.getServiceType().equals("6")) {
+                //婊℃剰搴︾粺璁� 锛堥�氳繃 subtask 鐨� id 鍘荤粺璁★級
+                List<Long> subtaskIds = serviceSubtaskList.stream().map(ServiceSubtaskRes::getId).collect(Collectors.toList());
+                serviceSubtaskDetailRatioExports = serviceSubtaskService.statQuestionOptionBySubtaskIds(subtaskIds, serviceSubtaskVO.getStartOutHospTime(), serviceSubtaskVO.getEndOutHospTime());
+            }
 
         }
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/SmsTempletController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/SmsTempletController.java
index 1342158..27237df 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/SmsTempletController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/SmsTempletController.java
@@ -6,6 +6,7 @@
 
 import cn.hutool.core.util.ObjectUtil;
 import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.utils.PageUtils;
 import com.ruoyi.common.utils.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -41,16 +42,18 @@
     //@PreAuthorize("@ss.hasPermi('smartor:smstemplet:list')")
     @PostMapping("/list")
     public Map<String, Object> list(@RequestBody SmsTemplet smsTemplet) {
+        smsTemplet.setPageNum(PageUtils.getOffset(smsTemplet.getPageNum(), smsTemplet.getPageSize()));
         if (StringUtils.isEmpty(smsTemplet.getUserName()) && StringUtils.isEmpty(smsTemplet.getWardCode()) && StringUtils.isEmpty(smsTemplet.getDeptCode())) {
             SysUser user = getLoginUser().getUser();
             smsTemplet.setUserName(user.getUserName());
             smsTemplet.setNickName(user.getNickName());
         }
+        List<SmsTemplet> list = smsTempletService.selectSmsTempletList(smsTemplet);
         //杩欎釜涓嶉渶瑕佸垎椤碉紝涓�涓瀹や篃涓嶄細鏈夊灏戞潯鐭俊妯℃澘
         smsTemplet.setPageNum(null);
         smsTemplet.setPageSize(null);
-        List<SmsTemplet> list = smsTempletService.selectSmsTempletList(smsTemplet);
-        return getDataTable3(ObjectUtil.isNotEmpty(list) ? list.size() : 0, list);
+        List<SmsTemplet> total = smsTempletService.selectSmsTempletList(smsTemplet);
+        return getDataTable3(ObjectUtil.isNotEmpty(total) ? total.size() : 0, list);
     }
 
     /**
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
index ed60483..7562a08 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
@@ -122,12 +122,14 @@
      */
 //    @IpWhitelist
     @GetMapping("/SSOLogin")
-    public RedirectView SSOLogin(@RequestParam(required = false) String campusid, @RequestParam(required = false) String deptId, String orgid, String userName, String token) {
+    public RedirectView SSOLogin(@RequestParam(required = false) String campusid, @RequestParam(required = false) String deptId, @RequestParam(required = false) String systype, String orgid, String userName, String token) {
         if (StringUtils.isEmpty(userName) && StringUtils.isEmpty(token) && StringUtils.isEmpty(orgid)) {
             throw new BaseException("鍙傛暟涓嶈兘涓虹┖");
         }
+        String path = null;
+        if (StringUtils.isEmpty(systype)) path = sysConfigService.selectConfigByKey("sys.qddz");
+        else path = sysConfigService.selectConfigByKey("sys.qddz.yd");
 
-        String path = sysConfigService.selectConfigByKey("sys.qddz");
         if (StringUtils.isEmpty(path)) {
             throw new BaseException("璇烽厤缃墠绔湴鍧�");
         }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java
index b4f6bac..b9ce0ce 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java
@@ -1,183 +1,154 @@
-package com.ruoyi.web.controller.tool;
-
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import com.ruoyi.common.core.controller.BaseController;
-import com.ruoyi.common.core.domain.R;
-import com.ruoyi.common.utils.StringUtils;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import io.swagger.annotations.ApiOperation;
-
-/**
- * swagger 鐢ㄦ埛娴嬭瘯鏂规硶
- * 
- * @author ruoyi
- */
-@Api("鐢ㄦ埛淇℃伅绠$悊")
-@RestController
-@RequestMapping("/test/user")
-public class TestController extends BaseController
-{
-    private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
-    {
-        users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
-        users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
-    }
-
-    @ApiOperation("鑾峰彇鐢ㄦ埛鍒楄〃")
-    @GetMapping("/list")
-    public R<List<UserEntity>> userList()
-    {
-        List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
-        return R.ok(userList);
-    }
-
-    @ApiOperation("鑾峰彇鐢ㄦ埛璇︾粏")
-    @ApiImplicitParam(name = "userId", value = "鐢ㄦ埛ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
-    @GetMapping("/{userId}")
-    public R<UserEntity> getUser(@PathVariable Integer userId)
-    {
-        if (!users.isEmpty() && users.containsKey(userId))
-        {
-            return R.ok(users.get(userId));
-        }
-        else
-        {
-            return R.fail("鐢ㄦ埛涓嶅瓨鍦�");
-        }
-    }
-
-    @ApiOperation("鏂板鐢ㄦ埛")
-    @ApiImplicitParams({
-        @ApiImplicitParam(name = "userId", value = "鐢ㄦ埛id", dataType = "Integer", dataTypeClass = Integer.class),
-        @ApiImplicitParam(name = "username", value = "鐢ㄦ埛鍚嶇О", dataType = "String", dataTypeClass = String.class),
-        @ApiImplicitParam(name = "password", value = "鐢ㄦ埛瀵嗙爜", dataType = "String", dataTypeClass = String.class),
-        @ApiImplicitParam(name = "mobile", value = "鐢ㄦ埛鎵嬫満", dataType = "String", dataTypeClass = String.class)
-    })
-    @PostMapping("/save")
-    public R<String> save(UserEntity user)
-    {
-        if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
-        {
-            return R.fail("鐢ㄦ埛ID涓嶈兘涓虹┖");
-        }
-        users.put(user.getUserId(), user);
-        return R.ok();
-    }
-
-    @ApiOperation("鏇存柊鐢ㄦ埛")
-    @PutMapping("/update")
-    public R<String> update(@RequestBody UserEntity user)
-    {
-        if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
-        {
-            return R.fail("鐢ㄦ埛ID涓嶈兘涓虹┖");
-        }
-        if (users.isEmpty() || !users.containsKey(user.getUserId()))
-        {
-            return R.fail("鐢ㄦ埛涓嶅瓨鍦�");
-        }
-        users.remove(user.getUserId());
-        users.put(user.getUserId(), user);
-        return R.ok();
-    }
-
-    @ApiOperation("鍒犻櫎鐢ㄦ埛淇℃伅")
-    @ApiImplicitParam(name = "userId", value = "鐢ㄦ埛ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
-    @DeleteMapping("/{userId}")
-    public R<String> delete(@PathVariable Integer userId)
-    {
-        if (!users.isEmpty() && users.containsKey(userId))
-        {
-            users.remove(userId);
-            return R.ok();
-        }
-        else
-        {
-            return R.fail("鐢ㄦ埛涓嶅瓨鍦�");
-        }
-    }
-}
-
-@ApiModel(value = "UserEntity", description = "鐢ㄦ埛瀹炰綋")
-class UserEntity
-{
-    @ApiModelProperty("鐢ㄦ埛ID")
-    private Integer userId;
-
-    @ApiModelProperty("鐢ㄦ埛鍚嶇О")
-    private String username;
-
-    @ApiModelProperty("鐢ㄦ埛瀵嗙爜")
-    private String password;
-
-    @ApiModelProperty("鐢ㄦ埛鎵嬫満")
-    private String mobile;
-
-    public UserEntity()
-    {
-
-    }
-
-    public UserEntity(Integer userId, String username, String password, String mobile)
-    {
-        this.userId = userId;
-        this.username = username;
-        this.password = password;
-        this.mobile = mobile;
-    }
-
-    public Integer getUserId()
-    {
-        return userId;
-    }
-
-    public void setUserId(Integer userId)
-    {
-        this.userId = userId;
-    }
-
-    public String getUsername()
-    {
-        return username;
-    }
-
-    public void setUsername(String username)
-    {
-        this.username = username;
-    }
-
-    public String getPassword()
-    {
-        return password;
-    }
-
-    public void setPassword(String password)
-    {
-        this.password = password;
-    }
-
-    public String getMobile()
-    {
-        return mobile;
-    }
-
-    public void setMobile(String mobile)
-    {
-        this.mobile = mobile;
-    }
-}
+//package com.ruoyi.web.controller.tool;
+//
+//import java.util.ArrayList;
+//import java.util.LinkedHashMap;
+//import java.util.List;
+//import java.util.Map;
+//
+//import org.springframework.web.bind.annotation.DeleteMapping;
+//import org.springframework.web.bind.annotation.GetMapping;
+//import org.springframework.web.bind.annotation.PathVariable;
+//import org.springframework.web.bind.annotation.PostMapping;
+//import org.springframework.web.bind.annotation.PutMapping;
+//import org.springframework.web.bind.annotation.RequestBody;
+//import org.springframework.web.bind.annotation.RequestMapping;
+//import org.springframework.web.bind.annotation.RestController;
+//import com.ruoyi.common.core.controller.BaseController;
+//import com.ruoyi.common.core.domain.R;
+//import com.ruoyi.common.utils.StringUtils;
+//import io.swagger.annotations.Api;
+//import io.swagger.annotations.ApiImplicitParam;
+//import io.swagger.annotations.ApiImplicitParams;
+//import io.swagger.annotations.ApiModel;
+//import io.swagger.annotations.ApiModelProperty;
+//import io.swagger.annotations.ApiOperation;
+//
+///**
+// * swagger 鐢ㄦ埛娴嬭瘯鏂规硶
+// *
+// * @author ruoyi
+// */
+//@Api("鐢ㄦ埛淇℃伅绠$悊")
+//@RestController
+//@RequestMapping("/test/user")
+//public class TestController extends BaseController {
+//    private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
+//
+//    {
+//        users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
+//        users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
+//    }
+//
+//    @ApiOperation("鑾峰彇鐢ㄦ埛鍒楄〃")
+//    @GetMapping("/list")
+//    public R<List<UserEntity>> userList() {
+//        List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
+//        return R.ok(userList);
+//    }
+//
+//    @ApiOperation("鑾峰彇鐢ㄦ埛璇︾粏")
+//    @ApiImplicitParam(name = "userId", value = "鐢ㄦ埛ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
+//    @GetMapping("/{userId}")
+//    public R<UserEntity> getUser(@PathVariable Integer userId) {
+//        if (!users.isEmpty() && users.containsKey(userId)) {
+//            return R.ok(users.get(userId));
+//        } else {
+//            return R.fail("鐢ㄦ埛涓嶅瓨鍦�");
+//        }
+//    }
+//
+//    @ApiOperation("鏂板鐢ㄦ埛")
+//    @ApiImplicitParams({@ApiImplicitParam(name = "userId", value = "鐢ㄦ埛id", dataType = "Integer", dataTypeClass = Integer.class), @ApiImplicitParam(name = "username", value = "鐢ㄦ埛鍚嶇О", dataType = "String", dataTypeClass = String.class), @ApiImplicitParam(name = "password", value = "鐢ㄦ埛瀵嗙爜", dataType = "String", dataTypeClass = String.class), @ApiImplicitParam(name = "mobile", value = "鐢ㄦ埛鎵嬫満", dataType = "String", dataTypeClass = String.class)})
+//    @PostMapping("/save")
+//    public R<String> save(UserEntity user) {
+//        if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) {
+//            return R.fail("鐢ㄦ埛ID涓嶈兘涓虹┖");
+//        }
+//        users.put(user.getUserId(), user);
+//        return R.ok();
+//    }
+//
+//    @ApiOperation("鏇存柊鐢ㄦ埛")
+//    @PutMapping("/update")
+//    public R<String> update(@RequestBody UserEntity user) {
+//        if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) {
+//            return R.fail("鐢ㄦ埛ID涓嶈兘涓虹┖");
+//        }
+//        if (users.isEmpty() || !users.containsKey(user.getUserId())) {
+//            return R.fail("鐢ㄦ埛涓嶅瓨鍦�");
+//        }
+//        users.remove(user.getUserId());
+//        users.put(user.getUserId(), user);
+//        return R.ok();
+//    }
+//
+//    @ApiOperation("鍒犻櫎鐢ㄦ埛淇℃伅")
+//    @ApiImplicitParam(name = "userId", value = "鐢ㄦ埛ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
+//    @GetMapping("/{userId}")
+//    public R<String> delete(@PathVariable Integer userId) {
+//        if (!users.isEmpty() && users.containsKey(userId)) {
+//            users.remove(userId);
+//            return R.ok();
+//        } else {
+//            return R.fail("鐢ㄦ埛涓嶅瓨鍦�");
+//        }
+//    }
+//}
+//
+//@ApiModel(value = "UserEntity", description = "鐢ㄦ埛瀹炰綋")
+//class UserEntity {
+//    @ApiModelProperty("鐢ㄦ埛ID")
+//    private Integer userId;
+//
+//    @ApiModelProperty("鐢ㄦ埛鍚嶇О")
+//    private String username;
+//
+//    @ApiModelProperty("鐢ㄦ埛瀵嗙爜")
+//    private String password;
+//
+//    @ApiModelProperty("鐢ㄦ埛鎵嬫満")
+//    private String mobile;
+//
+//    public UserEntity() {
+//
+//    }
+//
+//    public UserEntity(Integer userId, String username, String password, String mobile) {
+//        this.userId = userId;
+//        this.username = username;
+//        this.password = password;
+//        this.mobile = mobile;
+//    }
+//
+//    public Integer getUserId() {
+//        return userId;
+//    }
+//
+//    public void setUserId(Integer userId) {
+//        this.userId = userId;
+//    }
+//
+//    public String getUsername() {
+//        return username;
+//    }
+//
+//    public void setUsername(String username) {
+//        this.username = username;
+//    }
+//
+//    public String getPassword() {
+//        return password;
+//    }
+//
+//    public void setPassword(String password) {
+//        this.password = password;
+//    }
+//
+//    public String getMobile() {
+//        return mobile;
+//    }
+//
+//    public void setMobile(String mobile) {
+//        this.mobile = mobile;
+//    }
+//}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
index b5e2021..571f2ac 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -108,7 +108,7 @@
                 // 杩囨护璇锋眰
                 .authorizeRequests()
                 // 瀵逛簬鐧诲綍login 娉ㄥ唽register 楠岃瘉鐮乧aptchaImage 鍏佽鍖垮悕璁块棶
-                .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("/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","/smartor/shphone/getFirstQues","/smartor/shphone/processResust","/smartor/shphone/addOutboundInstance").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()
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java
index 36695a2..70633ec 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java
@@ -1,6 +1,7 @@
 package com.ruoyi.framework.config;
 
 import com.ruoyi.common.utils.Threads;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.concurrent.BasicThreadFactory;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -15,6 +16,7 @@
  *
  * @author ruoyi
  **/
+@Slf4j
 @Configuration
 public class ThreadPoolConfig
 {
@@ -34,12 +36,22 @@
     public ThreadPoolTaskExecutor threadPoolTaskExecutor()
     {
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
-        executor.setMaxPoolSize(maxPoolSize);
+        // 鏍稿績绾跨▼姹犲ぇ灏�
         executor.setCorePoolSize(corePoolSize);
+        // 鏈�澶у彲鍒涘缓鐨勭嚎绋嬫暟
+        executor.setMaxPoolSize(maxPoolSize);
+        // 闃熷垪鏈�澶ч暱搴�
         executor.setQueueCapacity(queueCapacity);
+        // 绾跨▼姹犵淮鎶ょ嚎绋嬫墍鍏佽鐨勭┖闂叉椂闂�
         executor.setKeepAliveSeconds(keepAliveSeconds);
-        // 绾跨▼姹犲鎷掔粷浠诲姟(鏃犵嚎绋嬪彲鐢�)鐨勫鐞嗙瓥鐣�
+        // 绾跨▼鍚嶇О鍓嶇紑
+        executor.setThreadNamePrefix("async-task-executor-");
+        // 璁剧疆绾跨▼宸ュ巶 (鐢ㄤ簬缁欑嚎绋嬪懡鍚嶏紝渚夸簬鎺掓煡闂)
+        executor.setThreadFactory(new BasicThreadFactory.Builder().namingPattern("async-task-%d").daemon(true).build());
+        // 绾跨▼姹犲鎷掔粷浠诲姟 (鏃犵嚎绋嬪彲鐢�) 鐨勫鐞嗙瓥鐣� - 璋冪敤鑰呰繍琛岀瓥鐣�
         executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        // 鍒濆鍖�
+        executor.initialize();
         return executor;
     }
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
index 797600a..2308da0 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -133,6 +133,7 @@
         SysUserDept sysUserDept = new SysUserDept();
         sysUserDept.setUserId(sysUser.getUserId());
         sysUserDept.setDeptType(sysUser.getSearchscope());
+        sysUserDept.setOrgid(sysUser.getOrgid());
         List<SysUserDept> sysUserDeptKSs = null;
         List<SysUserDept> sysUserDeptBQs = null;
         if (StringUtils.isNotEmpty(sysUser.getSearchscope()) && sysUser.getSearchscope().equals("0")) {
diff --git a/ruoyi-system/src/main/resources/mapper/system/SmsTempletMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SmsTempletMapper.xml
index 3305c94..7dd1c07 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SmsTempletMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SmsTempletMapper.xml
@@ -67,6 +67,7 @@
         <if test="wardCode != null  and wardCode != ''">and ward_code = #{wardCode}</if>
         <if test="userName != null  and userName != ''">and user_name = #{userName}</if>
         <if test="nickName != null  and nickName != ''">and nick_name = #{nickName}</if>
+        <if test="pageSize != null  and pageNum != null">limit ${pageSize} OFFSET ${pageNum}</if>
     </select>
 
     <select id="selectSmsTempletByTempletid" parameterType="Long" resultMap="SmsTempletResult">
diff --git a/smartor/src/main/java/com/smartor/domain/PhoneCallBackSHVO.java b/smartor/src/main/java/com/smartor/domain/PhoneCallBackSHVO.java
new file mode 100644
index 0000000..34dcb5a
--- /dev/null
+++ b/smartor/src/main/java/com/smartor/domain/PhoneCallBackSHVO.java
@@ -0,0 +1,50 @@
+package com.smartor.domain;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 鐢佃瘽闂鍝嶅簲(涓夋眹)
+ *
+ * @author ls
+ * 26
+ */
+@Data
+public class PhoneCallBackSHVO {
+
+    /**
+     * 瀛愪换鍔D
+     */
+    @ApiModelProperty(value = "瀛愪换鍔D")
+    private Long subId;
+
+    /**
+     * 闂ID
+     */
+    @ApiModelProperty(value = "闂ID")
+    private Long scriptId;
+
+    /**
+     * 浠诲姟妯℃澘ID
+     */
+    @ApiModelProperty(value = "浠诲姟妯℃澘ID")
+    private Long taskTemplateid;
+
+    /**
+     * 鍙互瀵瑰綋鍓嶉�氶亾鐨勯煶閲忚繘琛岄�傚綋璋冩暣,鍙栧�艰寖鍥淬��-4,4銆�
+     */
+    @ApiModelProperty(value = "搴忓彿")
+    private Integer sort;
+
+
+    @ApiModelProperty(value = "闂鍐呭")
+    private String scriptContent;
+
+
+    @ApiModelProperty(value = "閫夐」")
+    private String option;
+
+    @ApiModelProperty(value = "娴佺▼鐘舵�侊細0缁撴潫   1杩涜涓�")
+    private String status = "1";
+
+}
diff --git a/smartor/src/main/java/com/smartor/domain/PhoneCallResultYQVO.java b/smartor/src/main/java/com/smartor/domain/PhoneCallResultYQVO.java
new file mode 100644
index 0000000..18fbbb1
--- /dev/null
+++ b/smartor/src/main/java/com/smartor/domain/PhoneCallResultYQVO.java
@@ -0,0 +1,74 @@
+package com.smartor.domain;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 鐢佃瘽ASR鍥炶皟璇锋眰(闆ㄧ划)
+ *
+ * @author ls
+ * @date 2024-08-8
+ */
+@Data
+public class PhoneCallResultYQVO {
+
+    @ApiModelProperty(value = "浠诲姟缂栧彿(杩欓噷瀛樺湪鐨勫氨鏄痵ubtaskID)")
+    private String taskid;
+
+
+    /**
+     * 褰撳墠鍛煎彨鐨勭洰鏍囧彿鐮�
+     */
+    @ApiModelProperty(value = "褰撳墠鍛煎彨鐨勭洰鏍囧彿鐮�")
+    private String phone;
+
+    /**
+     * 褰撳墠鍥炶皟鐨勮姹傜被鍨嬶紝鍖呮嫭锛欰srCallback: ASR鏂囨湰鍥炶皟    DtmfCallback:鏀跺埌鎸夐敭鍥炶皟       SilentCallback:闈欓粯鍥炶皟      PlayEvent:闊充箰鎾斁寮�濮嬨�佺粨鏉熶簨浠跺洖璋�
+     */
+    @ApiModelProperty(value = "褰撳墠鍥炶皟鐨勮姹傜被鍨嬶紝鍖呮嫭锛欰srCallback: ASR鏂囨湰鍥炶皟    DtmfCallback:鏀跺埌鎸夐敭鍥炶皟       SilentCallback:闈欓粯鍥炶皟      PlayEvent:闊充箰鎾斁寮�濮嬨�佺粨鏉熶簨浠跺洖璋�")
+    private String operate;
+
+    /**
+     * asr鍥炵瓟鐨勫唴瀹�
+     */
+    @ApiModelProperty(value = "asr鍥炵瓟鐨勫唴瀹�")
+    private String asrResult;
+
+    /**
+     * 瀛愪换鍔D
+     */
+    @ApiModelProperty(value = "瀛愪换鍔D")
+    private Long subId;
+
+    /**
+     * 闂ID
+     */
+    @ApiModelProperty(value = "闂ID")
+    private Long scriptId;
+
+    /**
+     * 浠诲姟妯℃澘ID
+     */
+    @ApiModelProperty(value = "浠诲姟妯℃澘ID")
+    private Long taskTemplateid;
+
+    /**
+     * 鍙互瀵瑰綋鍓嶉�氶亾鐨勯煶閲忚繘琛岄�傚綋璋冩暣,鍙栧�艰寖鍥淬��-4,4銆�
+     */
+    @ApiModelProperty(value = "搴忓彿")
+    private Integer sort;
+
+
+    @ApiModelProperty(value = "閫氳繃搴撳尮閰嶇殑缁撴灉")
+    private String scriptContent;
+
+    @ApiModelProperty(value = "鏈烘瀯ID")
+    private String orgid;
+
+    @ApiModelProperty(value = "uuid")
+    private String uuid;
+
+    @ApiModelProperty(value = "guid")
+    private String guid;
+
+}
diff --git a/smartor/src/main/java/com/smartor/domain/ServiceOutPath.java b/smartor/src/main/java/com/smartor/domain/ServiceOutPath.java
index bf18264..5f04aa7 100644
--- a/smartor/src/main/java/com/smartor/domain/ServiceOutPath.java
+++ b/smartor/src/main/java/com/smartor/domain/ServiceOutPath.java
@@ -85,5 +85,21 @@
     @ApiModelProperty(value = "鐥呬汉淇℃伅")
     private PatArchive patArchive;
 
+
+    /**
+     * 鏈姞瀵嗙殑浠诲姟ID
+     */
+    @ApiModelProperty("鏈姞瀵嗙殑浠诲姟ID")
+    @Excel(name = "鏈姞瀵嗙殑浠诲姟ID")
+    private Long taskId;
+
+
+    /**
+     * 鏈姞瀵嗙殑瀛愪换鍔D
+     */
+    @ApiModelProperty("鏈姞瀵嗙殑瀛愪换鍔D")
+    @Excel(name = "鏈姞瀵嗙殑瀛愪换鍔D")
+    private Long subId;
+
 }
 
diff --git a/smartor/src/main/java/com/smartor/domain/VO/ServiceSubtaskVO.java b/smartor/src/main/java/com/smartor/domain/VO/ServiceSubtaskVO.java
index 1483955..82cd620 100644
--- a/smartor/src/main/java/com/smartor/domain/VO/ServiceSubtaskVO.java
+++ b/smartor/src/main/java/com/smartor/domain/VO/ServiceSubtaskVO.java
@@ -94,8 +94,8 @@
     /**
      * 鏈嶅姟绫诲瀷(1銆佺洃娴嬭瘎浼帮紱2銆佸嚭闄㈤殢璁匡紱3銆侀棬璇婇殢璁匡紱4銆佸鏁欏叧鎬�锛�5銆佸璇婇�氱煡锛�6銆佹弧鎰忓害璋冩煡锛�7銆佹偅鑰呮姤鍛婏紱 8銆佸叾浠栭�氱煡)
      */
-    @Excel(name = "鏈嶅姟绫诲瀷(1銆佺洃娴嬭瘎浼帮紱2銆佸嚭闄㈤殢璁匡紱3銆侀棬璇婇殢璁匡紱4銆佸鏁欏叧鎬�锛�5銆佸璇婄鐞嗭紱6銆佹弧鎰忓害璋冩煡锛�7銆佹偅鑰呮姤鍛婏紱 8銆佸叾浠栭�氱煡 9浣撴闅忚 10.鍖绘妧闅忚  11锛屽奖鍍忎笓绉戦殢璁�  12銆佸績鐢典笓绉戦殢璁匡紝 13涓撶闅忚)")
-    @ApiModelProperty(value = "鏈嶅姟绫诲瀷(1銆佺洃娴嬭瘎浼帮紱2銆佸嚭闄㈤殢璁匡紱3銆侀棬璇婇殢璁匡紱4銆佸鏁欏叧鎬�锛�5銆佸璇婄鐞嗭紱6銆佹弧鎰忓害璋冩煡锛�7銆佹偅鑰呮姤鍛婏紱 8銆佸叾浠栭�氱煡 9浣撴闅忚 10.鍖绘妧闅忚  11锛屽奖鍍忎笓绉戦殢璁�  12銆佸績鐢典笓绉戦殢璁匡紝 13涓撶闅忚)")
+    @Excel(name = "鏈嶅姟绫诲瀷(鏈嶅姟绫诲瀷(1銆佺洃娴嬭瘎浼帮紱2銆佸嚭闄㈤殢璁匡紱3銆侀棬璇婇殢璁匡紱4銆佸鏁欏叧鎬�(鍑洪櫌)  5銆佸璇婄鐞嗭紱6銆佷綇闄㈡弧鎰忓害璋冩煡锛�7銆佹偅鑰呮姤鍛婏紱 8銆佸叾浠栭�氱煡 9浣撴闅忚 10.鍖绘妧闅忚  11锛屽奖鍍忎笓绉戦殢璁�  12銆佸績鐢典笓绉戦殢璁匡紝 13涓撶闅忚   14銆侀棬璇婃弧鎰忓害璋冩煡  15鎶曡瘔寤鸿 16璇鹃闅忚  17銆佸鏁欏叧鎬�(鍏ラ櫌)  18銆佸叆闄㈤殢璁�)")
+    @ApiModelProperty(value = "鏈嶅姟绫诲瀷(鏈嶅姟绫诲瀷(1銆佺洃娴嬭瘎浼帮紱2銆佸嚭闄㈤殢璁匡紱3銆侀棬璇婇殢璁匡紱4銆佸鏁欏叧鎬�(鍑洪櫌)  5銆佸璇婄鐞嗭紱6銆佷綇闄㈡弧鎰忓害璋冩煡锛�7銆佹偅鑰呮姤鍛婏紱 8銆佸叾浠栭�氱煡 9浣撴闅忚 10.鍖绘妧闅忚  11锛屽奖鍍忎笓绉戦殢璁�  12銆佸績鐢典笓绉戦殢璁匡紝 13涓撶闅忚   14銆侀棬璇婃弧鎰忓害璋冩煡  15鎶曡瘔寤鸿 16璇鹃闅忚  17銆佸鏁欏叧鎬�(鍏ラ櫌)  18銆佸叆闄㈤殢璁�  19鎵嬫湳闅忚  20 鎮h�呭紓甯告姤鍛婅〃)")
     private String serviceType;
 
     /**
diff --git a/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java b/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java
index c57c908..3671f75 100644
--- a/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java
+++ b/smartor/src/main/java/com/smartor/mapper/ServiceSubtaskMapper.java
@@ -259,9 +259,21 @@
     /**
      * 缁熻闂鐨勯�夐」鐨勭櫨鍒嗘瘮
      *
-     * @param taskIds
+     * @param taskIds           浠诲姟 ID 鍒楄〃 (鐢ㄤ簬鏈嶅姟绫诲瀷 2)
+     * @param startOutHospTime  
+     * @param endOutHospTime    
      * @return
      */
     List<ServiceSubtaskDetailRatioExport> statQuestionOption(@Param("taskIds") List<Long> taskIds, @Param("startOutHospTime") Date startOutHospTime, @Param("endOutHospTime") Date endOutHospTime);
 
+    /**
+     * 鏍规嵁瀛愪换鍔� ID 缁熻闂鐨勯�夐」鐨勭櫨鍒嗘瘮锛堢敤浜庢弧鎰忓害缁熻 serviceType=6锛�
+     *
+     * @param subtaskIds        瀛愪换鍔� ID 鍒楄〃 (鍙兘鍗曚釜 taskid 涓嬬殑鎵�鏈夊瓙浠诲姟 id)
+     * @param startOutHospTime  
+     * @param endOutHospTime    
+     * @return
+     */
+    List<ServiceSubtaskDetailRatioExport> statQuestionOptionBySubtaskIds(@Param("subtaskIds") List<Long> subtaskIds, @Param("startOutHospTime") Date startOutHospTime, @Param("endOutHospTime") Date endOutHospTime);
+
 }
diff --git a/smartor/src/main/java/com/smartor/service/IServicePhoneService.java b/smartor/src/main/java/com/smartor/service/IServicePhoneService.java
new file mode 100644
index 0000000..2899603
--- /dev/null
+++ b/smartor/src/main/java/com/smartor/service/IServicePhoneService.java
@@ -0,0 +1,22 @@
+package com.smartor.service;
+
+import com.smartor.domain.*;
+import com.smartor.domain.VO.HeLibraryCountVO;
+import com.smartor.domain.VO.ServiceSubtaskCotinueCountVO;
+import com.smartor.domain.VO.TransferDeptVO;
+import com.smartor.domain.entity.ServiceSubtaskEntity;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 涓夋眹鐢佃瘽鏈嶅姟
+ *
+ * @author ruoyi
+ * @date 2026-08-27
+ */
+public interface IServicePhoneService {
+    OutboundInstanceResVO addOutboundInstance(OutboundConfigAddReqVO request);
+}
diff --git a/smartor/src/main/java/com/smartor/service/IServiceSubtaskService.java b/smartor/src/main/java/com/smartor/service/IServiceSubtaskService.java
index 93c578b..8662f84 100644
--- a/smartor/src/main/java/com/smartor/service/IServiceSubtaskService.java
+++ b/smartor/src/main/java/com/smartor/service/IServiceSubtaskService.java
@@ -129,6 +129,10 @@
      */
     public PhoneCallBackYQVO phoneCallBackYQ(PhoneCallReqYQVO phoneCallReqYQVO);
 
+    public PhoneCallBackSHVO getFirstQues(PhoneCallReqYQVO phoneCallReqYQVO);
+
+    public PhoneCallBackSHVO processResust(PhoneCallResultYQVO phoneCallReqYQVO);
+
     /**
      * 闆ㄧ划浠诲姟鎷夊彇
      *
@@ -202,13 +206,21 @@
     Map<String, Object> smsSubTask(Long subid);
 
     /**
-     * 缁熻闂鐨勯�夐」鐨勭櫨鍒嗘瘮
+     * 缁熻闂鐨勯�夐」鐨勭櫨鍒嗘瘮 (鐢ㄤ簬鏈嶅姟绫诲瀷 2)
      *
      * @param taskIds
      * @return
      */
     public List<ServiceSubtaskDetailRatioExport> statQuestionOption(List<Long> taskIds, Date startOutHospTime, Date endOutHospTime);
 
+    /**
+     * 鏍规嵁瀛愪换鍔� ID 缁熻闂鐨勯�夐」鐨勭櫨鍒嗘瘮锛堢敤浜庢弧鎰忓害缁熻 serviceType=6锛�
+     *
+     * @param subtaskIds        瀛愪换鍔� ID 鍒楄〃
+     * @return
+     */
+    public List<ServiceSubtaskDetailRatioExport> statQuestionOptionBySubtaskIds(List<Long> subtaskIds, Date startOutHospTime, Date endOutHospTime);
+
     public String scanGenerateSubtask(ServiceTask serviceTaskVo);
 
     public Integer matchOptionIndex(String url, String questionText, String voiceText, List<IvrTaskTemplateTargetoption> options, String uuid);
diff --git a/smartor/src/main/java/com/smartor/service/impl/ServicPhoneServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/ServicPhoneServiceImpl.java
new file mode 100644
index 0000000..26a970c
--- /dev/null
+++ b/smartor/src/main/java/com/smartor/service/impl/ServicPhoneServiceImpl.java
@@ -0,0 +1,200 @@
+package com.smartor.service.impl;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.Gson;
+import com.ruoyi.common.core.domain.entity.SysDept;
+import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.core.service.IConfigService;
+import com.ruoyi.common.dx.MessageSend;
+import com.ruoyi.common.exception.base.BaseException;
+import com.ruoyi.common.utils.*;
+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.FtpService;
+import com.smartor.common.MtSubmitSmUtil;
+import com.smartor.common.ScheduleSubtaskBuilder;
+import com.smartor.config.PhoneUtils;
+import com.smartor.domain.DTO.ServiceSubtaskDetailDTO;
+import com.smartor.domain.*;
+import com.smartor.domain.VO.HeLibraryCountVO;
+import com.smartor.domain.VO.ServiceSubtaskCotinueCountVO;
+import com.smartor.domain.VO.TransferDeptVO;
+import com.smartor.domain.entity.ServiceSubtaskEntity;
+import com.smartor.mapper.*;
+import com.smartor.service.*;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.data.redis.core.ListOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+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;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * 鍗曚竴浠诲姟锛堥殢璁匡級Service涓氬姟灞傚鐞�
+ *
+ * @author ruoyi
+ * @date 2024-02-02
+ */
+@Slf4j
+@Service
+public class ServicPhoneServiceImpl implements IServicePhoneService {
+    @Value("${shurl}")
+    private String shurl;
+
+    @Value("${shversion}")
+    private String shversion;
+
+    /**
+     * 鏂板澶栧懠瀹炰緥閰嶇疆
+     *
+     * @param request 澶栧懠瀹炰緥閰嶇疆璇锋眰瀵硅薄
+     * @return 澶栧懠瀹炰緥閰嶇疆缁撴灉
+     * @throws BaseException 鎺ュ彛璋冪敤澶辫触鎴栨暟鎹В鏋愬紓甯告椂鎶涘嚭
+     */
+    @Override
+    public OutboundInstanceResVO addOutboundInstance(OutboundConfigAddReqVO request) {
+        // 1. 鍙傛暟鏍¢獙
+        validateRequest(request);
+
+        // 2. 鍙戦�� HTTP 璇锋眰
+        String responseJson = sendHttpPostRequest(shurl + shversion + "/config/addOutboundInstance", request);
+
+        // 3. 瑙f瀽鍝嶅簲骞惰繑鍥炵粨鏋�
+        return parseResponse(responseJson);
+    }
+
+    /**
+     * 鍙傛暟鏍¢獙
+     */
+    private void validateRequest(OutboundConfigAddReqVO request) {
+        if (request == null) {
+            throw new BaseException("璇锋眰鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        // 蹇呬紶鍙傛暟鏍¢獙
+        assertNotBlank(request.getName(), "椤圭洰鍚嶇О涓嶈兘涓虹┖");
+        assertNotBlank(request.getAgent(), "鍧愬腑鍙蜂笉鑳戒负绌�");
+        assertNotBlank(request.getTenantId(), "璧勬簮缁勫彿涓嶈兘涓虹┖");
+        assertNotBlank(request.getCallType(), "鍛煎彨绫诲瀷涓嶈兘涓虹┖");
+        assertNotBlank(request.getActionID(), "actionID 涓嶈兘涓虹┖");
+
+        // 鏉′欢蹇呭~鏍¢獙锛歩sVgc=0 鏃讹紝queueId 鍜� ratio 涓哄繀濉�
+        if ("0".equals(request.getIsVgc())) {
+            assertNotBlank(request.getQueueId(), "isVgc=0 鏃讹紝鎵ц鍧愬腑缁� ID 涓嶈兘涓虹┖");
+            assertNotBlank(request.getRatio(), "isVgc=0 鏃讹紝澶栧懠閫熺巼涓嶈兘涓虹┖");
+        }
+        // 鏉′欢蹇呭~鏍¢獙锛歩sVgc=1 鏃讹紝ivrId 涓哄繀濉�
+        else if ("1".equals(request.getIsVgc())) {
+            assertNotBlank(request.getIvrId(), "isVgc=1 鏃讹紝IVR 娴佺▼ ID 涓嶈兘涓虹┖");
+        }
+    }
+
+    /**
+     * 鍙戦�� POST HTTP 璇锋眰
+     *
+     * @param url     API 鍦板潃
+     * @param request 璇锋眰瀵硅薄
+     * @return 鏈嶅姟鍣ㄥ搷搴� JSON 瀛楃涓�
+     */
+    private String sendHttpPostRequest(String url, Object request) {
+        log.info("寮�濮嬭皟鐢ㄥ鍛煎疄渚嬮厤缃帴鍙o紝URL: {}", url);
+
+        Map<String, String> headers = buildHeaders();
+        String requestBody = new Gson().toJson(request);
+
+        String response = HttpUtils.sendPostByHeader(url, requestBody, headers);
+
+        if (StringUtils.isEmpty(response)) {
+            log.error("澶栧懠瀹炰緥閰嶇疆鎺ュ彛璋冪敤澶辫触锛屾湭杩斿洖鏈夋晥鏁版嵁锛孶RL: {}", url);
+            throw new BaseException("鎺ュ彛璋冪敤澶辫触锛屾湭杩斿洖鏈夋晥鏁版嵁");
+        }
+
+        log.info("澶栧懠瀹炰緥閰嶇疆鎺ュ彛璋冪敤鎴愬姛锛屽搷搴旓細{}", response);
+        return response;
+    }
+
+    /**
+     * 鏋勫缓 HTTP 璇锋眰澶�
+     */
+    private Map<String, String> buildHeaders() {
+        Map<String, String> headers = new HashMap<>(1);
+        headers.put("Content-Type", "application/json; charset=UTF-8");
+        return headers;
+    }
+
+    /**
+     * 瑙f瀽 HTTP 鍝嶅簲骞惰浆鎹负 OutboundInstanceResVO
+     *
+     * @param responseJson 鍝嶅簲 JSON 瀛楃涓�
+     * @return 澶栧懠瀹炰緥閰嶇疆鍝嶅簲瀵硅薄
+     * @throws BaseException 褰撳搷搴旂爜涓嶄负 200 鎴栧搷搴旀暟鎹В鏋愬け璐ユ椂鎶涘嚭
+     */
+    private OutboundInstanceResVO parseResponse(String responseJson) {
+        try {
+            JSONObject response = JSON.parseObject(responseJson);
+
+            // 妫�鏌ュ搷搴旂爜
+            Integer code = response.getInteger("code");
+            if (!"200".equals(code.toString())) {
+                String message = response.getString("message");
+                log.error("澶栧懠瀹炰緥閰嶇疆鎺ュ彛杩斿洖澶辫触锛宑ode: {}, message: {}", code, message);
+                throw new BaseException("鏂板澶栧懠瀹炰緥閰嶇疆澶辫触锛�" + message);
+            }
+
+            // 瑙f瀽 data 瀛楁
+            JSONObject data = response.getJSONObject("data");
+            if (data == null || data.isEmpty()) {
+                throw new BaseException("鎺ュ彛杩斿洖鏁版嵁涓虹┖");
+            }
+
+            return data.toJavaObject(OutboundInstanceResVO.class);
+
+        } catch (BaseException e) {
+            throw e;
+        } catch (Exception e) {
+            log.error("瑙f瀽澶栧懠瀹炰緥閰嶇疆鍝嶅簲寮傚父锛宺esponse: {}", responseJson, e);
+            throw new BaseException("瑙f瀽鍝嶅簲鏁版嵁寮傚父锛�" + e.getMessage());
+        }
+    }
+
+    /**
+     * 鏂█瀛楃涓查潪绌哄伐鍏锋柟娉�
+     *
+     * @param value   寰呮鏌ョ殑鍊�
+     * @param message 鏂█澶辫触鏃剁殑閿欒娑堟伅
+     * @throws BaseException 褰撳�间负绌烘椂鎶涘嚭
+     */
+    private void assertNotBlank(String value, String message) {
+        if (StringUtils.isBlank(value)) {
+            throw new BaseException(message);
+        }
+    }
+}
diff --git a/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskAnswerServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskAnswerServiceImpl.java
index 4fb489d..eb920d8 100644
--- a/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskAnswerServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskAnswerServiceImpl.java
@@ -21,6 +21,7 @@
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -163,8 +164,19 @@
         return serviceSubtaskAnswerMapper.deleteServiceSubtaskAnswerById(id);
     }
 
+    /**
+     * 淇濆瓨闂嵎绛旀 (寮傛澶勭悊锛屽揩閫熻繑鍥�)
+     *
+     * @param serviceSubTaskAnswerReq 绛旀璇锋眰
+     * @param flag 鏍囧織浣�
+     * @return 缁撴灉
+     */
     @Override
+    @Async("threadPoolTaskExecutor")
     public Integer saveQuestionAnswer(ServiceSubTaskAnswerReq serviceSubTaskAnswerReq, Long flag) {
+        String threadName = Thread.currentThread().getName();
+        log.info("[{}] 寮�濮嬪紓姝ュ鐞嗕繚瀛橀棶鍗风瓟妗�", threadName);
+        try {
         //鍙傛暟瑙e瘑
         Long tid = null;
         Long pid = null;
@@ -401,9 +413,13 @@
             }
 
         }
+        log.info("[{}] 瀹屾垚寮傛澶勭悊淇濆瓨闂嵎绛旀", Thread.currentThread().getName());
         return 1;
+    } catch (Exception e) {
+        log.error("[{}] 寮傛澶勭悊淇濆瓨闂嵎绛旀鍙戠敓寮傚父 : {},璇锋眰鐨勫璞′负锛歿}", Thread.currentThread().getName(), e.getMessage(), e,serviceSubTaskAnswerReq);
+        throw new RuntimeException("淇濆瓨闂嵎绛旀澶辫触", e);
     }
-
+}
     @Override
     public Integer saveQuestionDetail(ServiceSubTaskCacheReq serviceSubTaskCacheReq, Long flag) {
         Long tid = Long.valueOf(serviceSubTaskCacheReq.getParam1());
diff --git a/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
index 8dbae00..0588017 100644
--- a/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -8,10 +8,10 @@
 import com.google.gson.Gson;
 import com.ruoyi.common.core.domain.entity.SysDept;
 import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.core.service.IConfigService;
 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;
@@ -33,6 +33,7 @@
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.ObjectUtils;
+import org.checkerframework.checker.nullness.qual.NonNull;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -41,10 +42,8 @@
 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;
@@ -204,6 +203,8 @@
 
     @Value("${spring.profiles.active}")
     private String active;
+    @Autowired
+    private ServiceOutPathMapper serviceOutPathMapper;
 
     /**
      * 鏌ヨ鍗曚竴浠诲姟锛堥殢璁匡級
@@ -628,9 +629,42 @@
      */
     @Override
     public Map<String, Object> insertServiceSubtask(ServiceSubtask serviceSubtask) {
-        serviceSubtask.setCreateTime(DateUtils.getNowDate());
-        serviceSubtaskMapper.insertServiceSubtask(serviceSubtask);
+        //鍏堟煡璇竴涓嬭鎮h�呮槸鍚﹀凡缁忓垱寤烘牴鎹畇erviceType,sendstate,inhospid,patid,orgid
+        ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity();
+        serviceSubtaskVO.setServiceType(serviceSubtask.getServiceType());
+        serviceSubtaskVO.setSendstates(new ArrayList<>(Arrays.asList(1L, 2L, 3L, 5L, 7L)));
+        serviceSubtaskVO.setPatid(serviceSubtask.getPatid());
+        serviceSubtaskVO.setOrgid(serviceSubtask.getOrgid());
+        serviceSubtaskVO.setCampusid(serviceSubtask.getCampusid());
+        List<ServiceSubtask> serviceSubtasks = serviceSubtaskMapper.selectServiceSubtaskList(serviceSubtaskVO);
         RSAPublicKeyExample rsaPublicKeyExample = new RSAPublicKeyExample();
+        String format = null;
+        if (CollectionUtils.isNotEmpty(serviceSubtasks)) {
+            ServiceSubtask serviceSubtask1 = serviceSubtasks.get(0);
+            ServiceOutPath serviceOutPath = new ServiceOutPath();
+            serviceOutPath.setSubId(serviceSubtask1.getId());
+            List<ServiceOutPath> serviceOutPaths = serviceOutPathMapper.selectServiceOutPathList(serviceOutPath);
+            if (CollectionUtils.isNotEmpty(serviceOutPaths))
+                format = String.format("%03X", serviceOutPaths.get(0).getId());
+            else format = getOutPath(serviceSubtask1, rsaPublicKeyExample);
+            serviceSubtask = serviceSubtask1;
+        } else {
+            //濡傛灉涓嶅瓨鍦紝鍒欐柊澧�
+            serviceSubtask.setCreateTime(DateUtils.getNowDate());
+            serviceSubtaskMapper.insertServiceSubtask(serviceSubtask);
+            format = getOutPath(serviceSubtask, rsaPublicKeyExample);
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        if (StringUtils.isNotEmpty(format))
+            result.put("url", StringUtils.isNotEmpty(req_path) ? localIP + ":" + req_path + "/wt?p=" + format : localIP + "/wt?p=" + format);
+        else result.put("url", null);
+        result.put("subId", serviceSubtask.getId());
+        return result;
+    }
+
+    private String getOutPath(ServiceSubtask serviceSubtask, RSAPublicKeyExample rsaPublicKeyExample) {
+        String format;
         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);
@@ -640,17 +674,15 @@
         serviceOutPath.setCreateTime(new Date());
         serviceOutPath.setParam6(subId);
         serviceOutPath.setOrgid(serviceSubtask.getOrgid());
+        serviceOutPath.setTaskId(serviceSubtask.getTaskid());
+        serviceOutPath.setSubId(serviceSubtask.getId());
         iServiceOutPathService.insertServiceOutPath(serviceOutPath);
         //杞垚16杩涘埗
-        String format = String.format("%03X", serviceOutPath.getId());
+        format = String.format("%03X", serviceOutPath.getId());
         serviceOutPath.setRadix(format);
         serviceOutPath.setUpdateTime(new Date());
         iServiceOutPathService.updateServiceOutPath(serviceOutPath);
-
-        Map<String, Object> result = new HashMap<>();
-        result.put("url", StringUtils.isNotEmpty(req_path) ? localIP + ":" + req_path + "/wt?p=" + format : localIP + "/wt?p=" + format);
-        result.put("subId", serviceSubtask.getId());
-        return result;
+        return format;
     }
 
     /**
@@ -1071,8 +1103,7 @@
                 }
             }
 
-        }
-        else if (serviceTaskVO.getIsoperation() != null && serviceTaskVO.getIsoperation() == 2) {
+        } else if (serviceTaskVO.getIsoperation() != null && serviceTaskVO.getIsoperation() == 2) {
             //浠诲姟淇敼
             if (ObjectUtils.isNotEmpty(serviceTaskVO.getSendTimeslot()))
                 serviceTask.setSendTimeSlot(JSON.toJSONString(serviceTaskVO.getSendTimeslot()));
@@ -4941,6 +4972,16 @@
         return serviceSubtaskMapper.statQuestionOption(taskIds, startOutHospTime, endOutHospTime);
     }
 
+    @Override
+    public List<ServiceSubtaskDetailRatioExport> statQuestionOptionBySubtaskIds(List<Long> subtaskIds, Date startOutHospTime, Date endOutHospTime) {
+        //鍏堟竻鐞嗕竴涓嬮噸澶嶆暟鎹�
+        List<Long> repeatIds = serviceSubtaskDetailMapper.selectRepeatDetailIds();
+        if (!CollectionUtils.isEmpty(repeatIds)) {
+            serviceSubtaskDetailMapper.deleteRepeatDetailByIds(repeatIds);
+        }
+        return serviceSubtaskMapper.statQuestionOptionBySubtaskIds(subtaskIds, startOutHospTime, endOutHospTime);
+    }
+
     /**
      * 鏍囧噯鍖栭棶鍗风瓟妗堟枃鏈細鍘绘帀 A/B/C/D 鍗曞瓧姣嶅墠缂�鍜屽悗缁┖鏍�
      * 渚嬪 "A 鏄�" -> "鏄�"锛�"B 鍚�" -> "鍚�"
@@ -5225,7 +5266,7 @@
         String jsonString = jsonObject.toJSONString();
         String result = null;
 
-//        String url = "http://localhost:8099/matchOptionIndex";
+//        String url = "cc";
         if (StringUtils.isNotEmpty(url)) {
             try {
                 Map<String, String> headers = new HashMap<>();
@@ -5242,6 +5283,163 @@
             return -1;
         }
     }
+
+
+    public PhoneCallBackSHVO getFirstQues(PhoneCallReqYQVO phoneCallReqYQVO) {
+        //鐢ㄤ簬杩斿洖
+        PhoneCallBackSHVO phoneCallBackSHVO = new PhoneCallBackSHVO();
+
+        //鏍规嵁鎵嬫満鍙疯幏鍙栫敤鎴风殑鐨勫瓙浠诲姟淇℃伅
+        ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity();
+        serviceSubtaskVO.setPhone(phoneCallReqYQVO.getPhone());
+        serviceSubtaskVO.setType("1");
+        serviceSubtaskVO.setSendstate(2L);
+        List<ServiceSubtask> serviceSubtasks = serviceSubtaskMapper.selectServiceSubtaskList(serviceSubtaskVO);
+        if (CollectionUtils.isNotEmpty(serviceSubtasks)) {
+            ServiceSubtask serviceSubtask = serviceSubtasks.get(0);
+            IvrTaskTemplate ivrTaskTemplate = ivrTaskTemplateService.selectIvrTaskTemplateByID(serviceSubtask.getTemplateid());
+
+            //閫氳繃浠诲姟妯℃澘涓殑"绗竴娆¢棶棰樼紪鍙�"鑾峰彇绗竴涓棶棰�;
+            IvrTaskTemplateScript ivrTaskTemplateScript = null;
+            IvrTaskTemplateScript ivrTaskTemplateScript1 = new IvrTaskTemplateScript();
+            ivrTaskTemplateScript1.setTemplateID(ivrTaskTemplate.getId());
+            List<IvrTaskTemplateScript> ivrTaskTemplateScripts = iIvrTaskTemplateScriptService.selectIvrTaskTemplateScriptList(ivrTaskTemplateScript1);
+
+            for (IvrTaskTemplateScript ivrTaskTemplateScript2 : ivrTaskTemplateScripts) {
+                if (ivrTaskTemplate.getFirstQuestionNum() == Long.valueOf(ivrTaskTemplateScript2.getSort())) {
+                    ivrTaskTemplateScript = ivrTaskTemplateScript2;
+                    break;
+                }
+            }
+            //鑾峰彇寮�鍦虹櫧
+            ServiceTask serviceTask = serviceTaskService.selectServiceTaskByTaskid(serviceSubtask.getTaskid());
+
+            phoneCallBackSHVO.setSubId(serviceSubtask.getId());
+            phoneCallBackSHVO.setScriptId(ivrTaskTemplateScript.getId());
+            phoneCallBackSHVO.setSort(ivrTaskTemplateScript.getSort());
+            phoneCallBackSHVO.setTaskTemplateid(ivrTaskTemplateScript.getTemplateID());
+            phoneCallBackSHVO.setScriptContent(serviceTask.getKcb() + "," + ivrTaskTemplateScript.getScriptContent());
+        }
+        return phoneCallBackSHVO;
+    }
+
+
+    /**
+     * 涓夋眹ASR缁撴灉澶勭悊
+     *
+     * @param phoneCallResultYQVO
+     * @return
+     */
+    public PhoneCallBackSHVO processResust(PhoneCallResultYQVO phoneCallResultYQVO) {
+        PhoneCallBackSHVO phoneCallBackSHVO = new PhoneCallBackSHVO();
+        //閫氳繃scriptid锛岃幏鍙栨墍鏈夌殑缁撴灉
+        String url = configService.selectConfigByKey("sys.voice.match.ai.url", phoneCallResultYQVO.getOrgid());
+        ServiceSubtask serviceSubtask = serviceSubtaskMapper.selectServiceSubtaskById(phoneCallResultYQVO.getSubId());
+        IvrTaskTemplate ivrTaskTemplate = ivrTaskTemplateService.selectIvrTaskTemplateByID(serviceSubtask.getTemplateid());
+        IvrTaskTemplateScriptVO ivrTaskTemplateScriptVO = iIvrTaskTemplateScriptService.getTaskTempScriptInfoByid(Long.valueOf(phoneCallResultYQVO.getScriptId()));
+        Integer i = matchOptionIndex(url, phoneCallResultYQVO.getScriptContent(), phoneCallResultYQVO.getAsrResult(), ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList(), phoneCallResultYQVO.getUuid());
+        if (i >= 0) {
+            String optiondesc = ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(i).getOptiondesc();
+            //灏嗘偅鑰呯殑鍥炵瓟鍐欒繘service_subtask_detail涓�
+            ServiceSubTaskDetailReq serviceSubTaskDetailReq = new ServiceSubTaskDetailReq();
+            List<ServiceSubtaskDetail> serviceSubtaskDetailList = new ArrayList<>();
+            ivrTaskTemplateScriptVO.setQuestionResult(optiondesc);
+
+            PhoneCallReqYQVO phoneCallReqYQVO = new PhoneCallReqYQVO();
+            phoneCallReqYQVO.setTaskid("" + serviceSubtask.getId());
+            phoneCallReqYQVO.setPhone(phoneCallResultYQVO.getPhone());
+            phoneCallReqYQVO.setAsrtext(phoneCallResultYQVO.getAsrResult());
+            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(phoneCallResultYQVO.getGuid());
+            serviceSubTaskDetailReq.setOrgid(phoneCallResultYQVO.getOrgid());
+            saveQuestionAnswerPhone(serviceSubTaskDetailReq);
+
+            IvrTaskTemplateScript ivrTaskTemplateScript = new IvrTaskTemplateScript();
+            ivrTaskTemplateScript.setTemplateID(ivrTaskTemplateScriptVO.getTemplateID());
+            List<IvrTaskTemplateScript> ivrTaskTemplateScripts = iIvrTaskTemplateScriptService.selectIvrTaskTemplateScriptList(ivrTaskTemplateScript);
+
+            //鑾峰彇涓嬩竴棰�
+            for (IvrTaskTemplateScript script : ivrTaskTemplateScripts) {
+                if (ivrTaskTemplateScriptVO.getNextScriptno() == null || ivrTaskTemplateScriptVO.getNextScriptno() == 0) {
+                    ServiceTask serviceTask = serviceTaskService.selectServiceTaskByTaskid(serviceSubtask.getTaskid());
+                    phoneCallBackSHVO.setScriptContent(serviceTask.getJsy());
+                    phoneCallBackSHVO.setTaskTemplateid(script.getTemplateID());
+                    phoneCallBackSHVO.setSort(script.getSort());
+                    phoneCallBackSHVO.setScriptId(script.getId());
+                    phoneCallBackSHVO.setSubId(serviceSubtask.getId());
+                    phoneCallBackSHVO.setStatus("0");
+                } else if (script.getSort() == ivrTaskTemplateScriptVO.getNextScriptno().intValue()) {
+                    phoneCallBackSHVO.setScriptContent(script.getScriptContent());
+                    phoneCallBackSHVO.setTaskTemplateid(script.getTemplateID());
+                    phoneCallBackSHVO.setSort(script.getSort());
+                    phoneCallBackSHVO.setScriptId(script.getId());
+                    phoneCallBackSHVO.setSubId(serviceSubtask.getId());
+                    break;
+                }
+            }
+            //鎶婄紦瀛樻竻闄�
+            redisCache.deleteObject(phoneCallResultYQVO.getSubId() + "-" + phoneCallResultYQVO.getScriptId());
+        } else {
+            //鍐嶅皢閲嶅璇㈤棶
+            //璁板綍涓�涓嬭繖涓棶棰樿闂鐨勬鏁�
+            Object cacheObject = redisCache.getCacheObject(phoneCallResultYQVO.getSubId() + "-" + phoneCallResultYQVO.getScriptId());
+            if (cacheObject == null || (Integer) cacheObject < ivrTaskTemplate.getMateNum()) {
+
+
+                // 鑾峰彇閫夐」闆嗗悎涓殑 optiondesc 鐢ㄤ簬寮曞鎮h��
+                List<IvrTaskTemplateTargetoption> optionList = ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList();
+                String optionDescStr = "";
+                if (optionList != null && !optionList.isEmpty()) {
+                    optionDescStr = optionList.stream().map(IvrTaskTemplateTargetoption::getTargetvalue).filter(StringUtils::isNotEmpty).collect(Collectors.joining("鎴�"));
+                }
+
+                String scriptContent = "璇烽棶" + phoneCallResultYQVO.getScriptContent();
+                if (StringUtils.isNotEmpty(optionDescStr)) {
+                    scriptContent += "锛屼綘鍙互鍥炵瓟锛�" + optionDescStr;
+                }
+                phoneCallBackSHVO.setScriptContent(scriptContent);
+                phoneCallBackSHVO.setTaskTemplateid(phoneCallResultYQVO.getTaskTemplateid());
+                phoneCallBackSHVO.setSort(phoneCallResultYQVO.getSort());
+                phoneCallBackSHVO.setScriptId(phoneCallResultYQVO.getScriptId());
+                phoneCallBackSHVO.setSubId(phoneCallResultYQVO.getSubId());
+                if (cacheObject == null)
+                    redisCache.setCacheObject(phoneCallResultYQVO.getSubId() + "-" + phoneCallResultYQVO.getScriptId(), 1, 120, TimeUnit.MINUTES);
+                else
+                    redisCache.setCacheObject(phoneCallResultYQVO.getSubId() + "-" + phoneCallResultYQVO.getScriptId(), (Integer) cacheObject + 1, 120, TimeUnit.MINUTES);
+            } else if ((Integer) cacheObject >= ivrTaskTemplate.getMateNum()) {
+                //濡傛灉宸茬粡闂簡瑙勫畾娆℃暟锛屽氨涓嶉棶浜嗭紝缁х画闂笅涓�棰橈紙杩欎釜瑕佸晢閲忎竴涓嬶紝鏄户缁棶涓嬩竴棰橈紝杩樻槸鍋滀簡锛屾槸涓嶆槸瑕佸仛涓紑鍏筹級
+                IvrTaskTemplateScript ivrTaskTemplateScript = new IvrTaskTemplateScript();
+                ivrTaskTemplateScript.setTemplateID(ivrTaskTemplateScriptVO.getTemplateID());
+                List<IvrTaskTemplateScript> ivrTaskTemplateScripts = iIvrTaskTemplateScriptService.selectIvrTaskTemplateScriptList(ivrTaskTemplateScript);
+                //鑾峰彇涓嬩竴棰�
+                for (IvrTaskTemplateScript script : ivrTaskTemplateScripts) {
+                    if (script.getSort() == ivrTaskTemplateScriptVO.getNextScriptno().intValue()) {
+                        phoneCallBackSHVO.setScriptContent(script.getScriptContent());
+                        phoneCallBackSHVO.setTaskTemplateid(script.getTemplateID());
+                        phoneCallBackSHVO.setSort(script.getSort());
+                        phoneCallBackSHVO.setScriptId(script.getId());
+                        phoneCallBackSHVO.setSubId(serviceSubtask.getId());
+                        break;
+                    }
+                }
+                //鎶婄紦瀛樻竻闄�
+                redisCache.deleteObject(phoneCallResultYQVO.getSubId() + "-" + phoneCallResultYQVO.getScriptId());
+            }
+        }
+        return phoneCallBackSHVO;
+    }
+
 
     public PhoneCallBackYQVO AiMatch(String url, PhoneCallReqYQVO phoneCallReqYQVO, PhoneCallBackYQVO phoneCallBackYQVO, IvrTaskTemplateScriptVO ivrTaskTemplateScriptVO, ServiceSubtask serviceSubtask, IvrTaskTemplate ivrTaskTemplate, List<IvrTaskTemplateScript> ivrTaskTemplateScripts, String scriptId, Integer flag, String uuid) {
         PhoneCallBackYQVO back = null;
@@ -5470,14 +5668,13 @@
     }
 
     //鑾峰彇浠诲姟缁勪俊鎭�
-    private void findServiceTaskScheduleVO(ServiceTaskVO serviceTaskVO){
-        if(StringUtils.isNotEmpty(serviceTaskVO.getAppltype()) && serviceTaskVO.getAppltype().equals("5")){
+    private void findServiceTaskScheduleVO(ServiceTaskVO serviceTaskVO) {
+        if (StringUtils.isNotEmpty(serviceTaskVO.getAppltype()) && serviceTaskVO.getAppltype().equals("5")) {
             //浠诲姟缁勪俊鎭�
             ServiceTaskSchedule schedule = serviceTaskScheduleService.selectByTaskid(serviceTaskVO.getTaskid());
             if (ObjectUtils.isNotEmpty(schedule)) {
                 ServiceTaskScheduleVO serviceTaskScheduleVO = DtoConversionUtils.sourceToTarget(schedule, ServiceTaskScheduleVO.class);
-                List<ServiceTaskScheduleDetail> scheduleDetailList =
-                        serviceTaskScheduleService.selectDetailByScheduleid(schedule.getId());
+                List<ServiceTaskScheduleDetail> scheduleDetailList = serviceTaskScheduleService.selectDetailByScheduleid(schedule.getId());
                 serviceTaskScheduleVO.setDetailList(scheduleDetailList);
                 serviceTaskVO.setServiceTaskScheduleVO(serviceTaskScheduleVO);
             }
diff --git a/smartor/src/main/resources/mapper/smartor/ServiceOutPathMapper.xml b/smartor/src/main/resources/mapper/smartor/ServiceOutPathMapper.xml
index fd1a9fb..afedfde 100644
--- a/smartor/src/main/resources/mapper/smartor/ServiceOutPathMapper.xml
+++ b/smartor/src/main/resources/mapper/smartor/ServiceOutPathMapper.xml
@@ -22,6 +22,9 @@
         <result property="wardName" column="ward_name"/>
         <result property="deptCode" column="dept_code"/>
         <result property="deptName" column="dept_name"/>
+        <result property="taskId" column="task_id"/>
+        <result property="subId" column="sub_id"/>
+
     </resultMap>
 
     <sql id="selectServiceOutPathVo">
@@ -31,6 +34,8 @@
                param3,
                param5,
                param6,
+               task_id,
+               sub_id,
                create_time,
                update_time,
                radix,
@@ -87,6 +92,12 @@
         <if test="deptName != null  and deptName != ''">
             and dept_name=#{deptName}
         </if>
+        <if test="subId != null">
+            and sub_id=#{subId}
+        </if>
+        <if test="taskId != null">
+            and task_id=#{taskId}
+        </if>
     </select>
 
     <select id="selectServiceOutPathById" parameterType="Long"
@@ -125,7 +136,12 @@
             </if>
             <if test="deptName != null">dept_name,
             </if>
-
+            <if test="subId != null">
+                sub_id,
+            </if>
+            <if test="taskId != null ">
+                task_id,
+            </if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="param1 != null">#{param1},
@@ -153,6 +169,12 @@
             <if test="deptCode != null">#{deptCode},
             </if>
             <if test="deptName != null">#{deptName},
+            </if>
+            <if test="subId != null ">
+                #{subId},
+            </if>
+            <if test="taskId != null ">
+                #{taskId},
             </if>
         </trim>
     </insert>
@@ -202,6 +224,12 @@
             <if test="deptName != null">dept_name =
                 #{deptName},
             </if>
+            <if test="subId != null">
+                sub_id=#{subId},
+            </if>
+            <if test="taskId != null">
+                task_id=#{taskId},
+            </if>
         </trim>
         where id = #{id}
     </update>
diff --git a/smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml b/smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
index 1683cd0..118719e 100644
--- a/smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
+++ b/smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
@@ -396,7 +396,7 @@
         </if>
         <if test="deptOrDistrict==2">
             AND (1=1
-            <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
+            <if test="leavehospitaldistrictcodes != null">
                 AND leavehospitaldistrictcode IN
                 <foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="("
                          separator=","
@@ -404,7 +404,7 @@
                     #{leavehospitaldistrictcode}
                 </foreach>
             </if>
-            <if test=" leaveldeptcodes != null and leaveldeptcodes.size()>0">
+            <if test=" leaveldeptcodes != null">
                 OR deptcode IN
                 <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator=","
                          close=")">
@@ -3089,6 +3089,56 @@
         t.taskid
     </select>
 
+    <!-- 鏂版柟娉曪細鏍规嵁瀛愪换鍔� ID 缁熻闂閫夐」鐧惧垎姣� (鐢ㄤ簬婊℃剰搴︾粺璁� serviceType=6) -->
+    <select id="statQuestionOptionBySubtaskIds" resultType="com.smartor.domain.ServiceSubtaskDetailRatioExport">
+        SELECT
+        d.questiontext AS questiontext,
+        t.taskid AS taskid,
+        t.task_name AS taskName,
+        d.asrtext AS optionresult,
+        COUNT(*) AS count,
+        CONCAT(ROUND(COUNT(*) * 100.0 / t2.total_count, 2), '%') AS ratio
+        FROM
+        service_task t
+        INNER JOIN service_subtask s ON s.taskid = t.taskid
+        INNER JOIN service_subtask_detail d ON d.sub_id = s.id
+        INNER JOIN (
+        SELECT
+            d.questiontext,
+            COUNT(*) AS total_count
+        FROM
+            service_task t
+            INNER JOIN service_subtask s ON s.taskid = t.taskid
+            INNER JOIN service_subtask_detail d ON d.sub_id = s.id
+            WHERE s.id IN
+            <foreach collection="subtaskIds" item="subtaskId" open="(" separator="," close=")">
+                #{subtaskId}
+            </foreach>
+            AND s.sendstate = 6
+            AND d.del_flag=0
+            GROUP BY d.questiontext  -- 鈫� 鍏抽敭淇敼锛氭寜棰樼洰鍒嗙粍缁熻姣忎釜棰樼洰鐨勬�绘暟
+        ) t2 ON t2.questiontext = d.questiontext  -- 鈫� 鍏宠仈鍒板綋鍓嶉鐩�
+        WHERE s.id IN
+        <foreach collection="subtaskIds" item="subtaskId" open="(" separator="," close=")">
+            #{subtaskId}
+        </foreach>
+        AND s.sendstate = 6
+        AND d.del_flag=0
+      <if test="startOutHospTime != null">
+        AND date_format(s.endtime,'%y%m%d') &gt;= date_format(#{startOutHospTime},'%y%m%d')
+    </if>
+        <if test="endOutHospTime != null">
+            AND date_format(s.endtime,'%y%m%d') &lt;= date_format(#{endOutHospTime},'%y%m%d')
+        </if>
+        GROUP BY
+        t.taskid,
+        d.questiontext,
+        d.asrtext
+        ORDER BY
+        d.questiontext,
+        t.taskid
+    </select>
+
     <select id="selectServiceSubtaskListDeadLine" parameterType="com.smartor.domain.entity.ServiceSubtaskEntity"
             resultMap="ServiceSubtaskResult">
         <include refid="selectServiceSubtaskVo"/>

--
Gitblit v1.9.3