百度外呼平台对接。
This commit is contained in:
parent
43432e3d2b
commit
363d52d91e
@ -107,7 +107,7 @@ token:
|
|||||||
# 令牌有效期(默认30分钟)
|
# 令牌有效期(默认30分钟)
|
||||||
expireTime: 30
|
expireTime: 30
|
||||||
# 请求拦截白名单
|
# 请求拦截白名单
|
||||||
ant-matchers: /postDischarge/**,/testMobile/**,/postDischargeApplet/**
|
ant-matchers: /postDischarge/**,/testMobile/**,/postDischargeApplet/**,/api/**
|
||||||
|
|
||||||
## MyBatis-Plus配置
|
## MyBatis-Plus配置
|
||||||
mybatis-plus:
|
mybatis-plus:
|
||||||
@ -274,3 +274,18 @@ push-message-restrictions:
|
|||||||
number: 1
|
number: 1
|
||||||
#时间 : 单位,天
|
#时间 : 单位,天
|
||||||
time: 2
|
time: 2
|
||||||
|
|
||||||
|
# 爱医生平台对接
|
||||||
|
aifuv-robots:
|
||||||
|
# 接口地址
|
||||||
|
url: https://aifuv2cloud.aihealthx.cn/
|
||||||
|
# 密钥
|
||||||
|
secrectKey: lJayvsWsVUWDmWnNan1WzmH9OEOiwB
|
||||||
|
|
||||||
|
# 百度客悦·智能外呼平台
|
||||||
|
aiob:
|
||||||
|
# 请求地址
|
||||||
|
url: https://aiob-open.baidu.com/api
|
||||||
|
accessKey: b6d2d73cdf2d4d7ca2ccc84968accdb3
|
||||||
|
secretKey: 9262d2fe32544eaabce18331bd5ca2c5
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,80 @@
|
|||||||
|
package com.xinelu.manage.controller.aibo;
|
||||||
|
|
||||||
|
import com.xinelu.common.core.controller.BaseController;
|
||||||
|
import com.xinelu.common.core.domain.R;
|
||||||
|
import com.xinelu.manage.dto.aibo.CreateTaskDto;
|
||||||
|
import com.xinelu.manage.dto.aibo.TaskCallbackDto;
|
||||||
|
import com.xinelu.manage.service.aibo.IAIOBService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 百度客悦·智能外呼平台接口
|
||||||
|
* @author: haown
|
||||||
|
* @create: 2024-08-22 09:50
|
||||||
|
**/
|
||||||
|
@Api(tags = "百度客悦·智能外呼平台接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api")
|
||||||
|
public class AIOBController extends BaseController {
|
||||||
|
@Resource
|
||||||
|
public IAIOBService aiobService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取外呼平台accessToken
|
||||||
|
* @return 智能外呼平台 accessToken
|
||||||
|
* @Author haown
|
||||||
|
* @Date 2024-8-22 15:30
|
||||||
|
*/
|
||||||
|
@ApiOperation("获取accessToken")
|
||||||
|
@PostMapping("/getAccessToken")
|
||||||
|
public R<String> getAccessToken() {
|
||||||
|
return R.ok(aiobService.getAccessToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 创建任务
|
||||||
|
* @param createTaskDto 创建任务传输对象
|
||||||
|
* @return taskId 客悦·智能外呼平台任务唯一标识
|
||||||
|
* @Author haown
|
||||||
|
* @Date 2024-8-22 15:34
|
||||||
|
*/
|
||||||
|
@ApiOperation("创建任务")
|
||||||
|
@PostMapping("/createTask")
|
||||||
|
public R<String> createTask(CreateTaskDto createTaskDto) {
|
||||||
|
return R.ok(aiobService.createTask(createTaskDto));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 任务状态变更
|
||||||
|
* @param taskId 任务id
|
||||||
|
* @param taskStatus 修改状态 2:执行中,3:已暂停,4:已完成(如点击「终止」
|
||||||
|
* @return 状态码
|
||||||
|
* @Author haown
|
||||||
|
* @Date 2024-8-23 11:49
|
||||||
|
*/
|
||||||
|
@ApiOperation("任务状态变更")
|
||||||
|
@PostMapping("/updateTaskStatus")
|
||||||
|
public R<String> updateTaskStatus(String taskId, Integer taskStatus) {
|
||||||
|
int flag = aiobService.updateTaskStatus(taskId, taskStatus);
|
||||||
|
return flag > 0 ? R.ok() : R.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 任务单通电话回调
|
||||||
|
* @param taskCallbackDto 回调数据类型, 0-任务呼叫单通电话回调 1-号码组终态回调 2-任务状态变更回调 3-实时呼叫单通电话回调
|
||||||
|
* @return null
|
||||||
|
* @Author haown
|
||||||
|
* @Date 2024-8-29 11:15
|
||||||
|
*/
|
||||||
|
@ApiOperation("任务单通电话回调")
|
||||||
|
@PostMapping("/taskCallBack")
|
||||||
|
public R<String> taskCallBack(@RequestBody TaskCallbackDto taskCallbackDto) {
|
||||||
|
return R.ok(aiobService.taskCallBack(taskCallbackDto.getCallbackType(), taskCallbackDto.getData()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -145,6 +145,11 @@ public class ScriptInfo extends BaseEntity {
|
|||||||
*/
|
*/
|
||||||
private String robotPublishId;
|
private String robotPublishId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 话术中用到的变量,竖线隔开。来源于字段标签表的key
|
||||||
|
*/
|
||||||
|
private String variables;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
|||||||
@ -0,0 +1,47 @@
|
|||||||
|
package com.xinelu.manage.domain.scriptinfotaskinfo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 百度外呼话术任务临时表
|
||||||
|
* @author: haown
|
||||||
|
* @create: 2024-08-30 14:29
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@ApiModel(value = "百度外呼话术任务临时表", description = "script_info_task_info")
|
||||||
|
public class ScriptInfoTaskInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 话术表主键
|
||||||
|
*/
|
||||||
|
private Long scriptInfoId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 机器人ID
|
||||||
|
*/
|
||||||
|
private String robotId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务标识
|
||||||
|
*/
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
package com.xinelu.manage.dto.aibo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 创建任务传输对象
|
||||||
|
* @author: haown
|
||||||
|
* @create: 2024-08-22 14:52
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
public class CreateTaskDto {
|
||||||
|
/**
|
||||||
|
* 任务名称
|
||||||
|
*/
|
||||||
|
private String taskName;
|
||||||
|
/**
|
||||||
|
* 外呼机器人唯一标识
|
||||||
|
*/
|
||||||
|
private String robotId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务呼叫开始日期
|
||||||
|
*/
|
||||||
|
private String dialStartDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务呼叫结束日期
|
||||||
|
*/
|
||||||
|
private String dialEndDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 呼叫开始时间
|
||||||
|
*/
|
||||||
|
private String dialStartTime = "09:00";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 呼叫结束时间
|
||||||
|
*/
|
||||||
|
private String dialEndTime = "18:00";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 禁呼日期, 99-节假日;1-周一;2-周二;3-周三;4-周四;5-周五;6-周六;0-周日,默认为空,表示不限制禁呼日期
|
||||||
|
*/
|
||||||
|
private List<Integer> forbidDialDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否开启24小时空号检测
|
||||||
|
*/
|
||||||
|
private Boolean isOpenEmptyNum = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否开启12小时内停机检测
|
||||||
|
*/
|
||||||
|
private Boolean isOpenPhoneDown = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 号码类型过滤 1-400号码;2-800号码;3-手机号码;4-固话;5-95号码;6-96号码;7-其他
|
||||||
|
*/
|
||||||
|
private List<Integer> numTypeFilterList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务拨号完成后是否进入完成状态, 0:拨号完成后任务不结束 1:拨号完成后任务结束 默认值为1
|
||||||
|
*/
|
||||||
|
private Integer callFinishTaskEnd = 0;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package com.xinelu.manage.dto.aibo;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 客户名单传输对象
|
||||||
|
* @author: haown
|
||||||
|
* @create: 2024-08-23 15:52
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
public class CustomerInfoDto {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用方的业务随路数据, 字符串,百度侧原文回传
|
||||||
|
*/
|
||||||
|
private String extJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 号码1;号码2;号码3, 最多5个号码,英文分号分隔,支持明文或密文
|
||||||
|
*/
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户指定归属地,为空则默认使用号码实际归属地,实际行政区域即可无格式要求,"-"分隔开即可
|
||||||
|
*/
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 名单的变量var map,名单外呼时需要用到的变量,{"key1": "value1","key2": "value2"}
|
||||||
|
*/
|
||||||
|
private JSONObject var;
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package com.xinelu.manage.dto.aibo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 导入名单传输对象
|
||||||
|
* @author: haown
|
||||||
|
* @create: 2024-08-23 15:10
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
public class ImportTaskDto {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务Id
|
||||||
|
*/
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密类型, 1:系统加密,即被叫号码采用系统的加密方式,AES128加密;
|
||||||
|
* 2:不加密,即被叫号码为明文;
|
||||||
|
* 3:自定义加密,即被叫号码采用客户自定义的加密方式,需在配置台-隐私配置-其他配置中配置自定义加解密服务地址,便于请求解密
|
||||||
|
*/
|
||||||
|
private Integer secretType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密钥ID,加密类型为系统加密时,必填
|
||||||
|
*/
|
||||||
|
private Integer secretId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 明文, 字符串,长度小于等于20, 如果加密类型为系统加密,则必填
|
||||||
|
*/
|
||||||
|
private String plainText;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密文,字符串,加密类型为系统加密时,必填
|
||||||
|
*/
|
||||||
|
private String cipherText;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客户名单list,每一次最多只能导入1000个号码组,可以多次导入同一个任务
|
||||||
|
*/
|
||||||
|
private List<CustomerInfoDto> customerInfoList;
|
||||||
|
}
|
||||||
@ -0,0 +1,169 @@
|
|||||||
|
package com.xinelu.manage.dto.aibo;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 任务单通电话回调传输data
|
||||||
|
* @author: haown
|
||||||
|
* @create: 2024-08-29 09:36
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
public class TaskCallbackDataDto {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通话唯一标识
|
||||||
|
*/
|
||||||
|
private String sessionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 租户唯一标识
|
||||||
|
*/
|
||||||
|
private Long tenantId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务标识
|
||||||
|
*/
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务名称
|
||||||
|
*/
|
||||||
|
private String taskName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 机器人ID
|
||||||
|
*/
|
||||||
|
private String robotId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 外呼机器人名称
|
||||||
|
*/
|
||||||
|
private String robotName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 号码组唯一标识,导入名单后,返回的名单号码组对应标识
|
||||||
|
*/
|
||||||
|
private Long memberId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 被叫号码
|
||||||
|
*/
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拨打次数
|
||||||
|
*/
|
||||||
|
private Integer callTimes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主叫号码
|
||||||
|
*/
|
||||||
|
private String callerNum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接通状态,1-已接通 0-未接通
|
||||||
|
*/
|
||||||
|
private Integer endType;
|
||||||
|
/**
|
||||||
|
* 呼叫类型,0-首次呼叫;1-重试;2-预约呼叫;3-实时呼叫
|
||||||
|
*/
|
||||||
|
private Integer callType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未接通原因
|
||||||
|
*/
|
||||||
|
private String endTypeReason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成通话录音唯一标识,可通过该标识,获取录音
|
||||||
|
*/
|
||||||
|
private String contactUUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件id,名单导入任务时生成的文件ID
|
||||||
|
*/
|
||||||
|
private Long field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 信息收集内容
|
||||||
|
*/
|
||||||
|
private JSONObject collectInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会话还原记录
|
||||||
|
*/
|
||||||
|
private JSONArray record;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拨号总时长,单位为秒
|
||||||
|
*/
|
||||||
|
private Integer durationTimeLen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 振铃时长,单位为秒
|
||||||
|
*/
|
||||||
|
private Integer ringingTimeLen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话时长,单位为秒
|
||||||
|
*/
|
||||||
|
private Integer talkingTimeLen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 呼叫开始时间-Unix时间戳(单位:毫秒)
|
||||||
|
*/
|
||||||
|
private Long startTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 振铃开始时间-Unix时间戳(单位:毫秒)
|
||||||
|
*/
|
||||||
|
private Long ringStartTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通话开始时间-Unix时间戳(单位:毫秒),未接通显示'-',已接通会有值
|
||||||
|
*/
|
||||||
|
private Long talkingStartTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 呼叫结束时间-Unix时间戳(单位:毫秒)
|
||||||
|
*/
|
||||||
|
private Long endTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 意向,在外呼机器人-流程节点-信息收集,配置key为「意向」,对应的value值
|
||||||
|
*/
|
||||||
|
private String intent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动作,HUNGUP:挂机
|
||||||
|
*/
|
||||||
|
private List<String> action;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否机器人主动挂机
|
||||||
|
*/
|
||||||
|
private Boolean isRobotHangup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变量,导入名单的变量
|
||||||
|
*/
|
||||||
|
private JSONObject dialogVar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信变量
|
||||||
|
*/
|
||||||
|
private JSONObject smsVar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 来自导入信息
|
||||||
|
*/
|
||||||
|
private String extJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转接结果,字段为空或值为0未发起,1成功,-1失败
|
||||||
|
*/
|
||||||
|
private Integer transResult;
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package com.xinelu.manage.dto.aibo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 任务单通电话回调传输对象
|
||||||
|
* @author: haown
|
||||||
|
* @create: 2024-08-29 14:06
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
public class TaskCallbackDto {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回调数据类型, 0-任务呼叫单通电话回调 1-号码组终态回调 2-任务状态变更回调 3-实时呼叫单通电话回调
|
||||||
|
*/
|
||||||
|
private Integer callbackType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务单通电话回调传输data
|
||||||
|
*/
|
||||||
|
private TaskCallbackDataDto data;
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package com.xinelu.manage.mapper.scriptinfotaskinfo;
|
||||||
|
|
||||||
|
import com.xinelu.manage.domain.scriptinfotaskinfo.ScriptInfoTaskInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 百度外呼话术任务临时表Mapper接口
|
||||||
|
*
|
||||||
|
* @author haown
|
||||||
|
* @date 2024-08-30
|
||||||
|
*/
|
||||||
|
public interface ScriptInfoTaskInfoMapper {
|
||||||
|
|
||||||
|
String getByScriptInfoId(Long scriptInfoId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增百度外呼话术任务临时表
|
||||||
|
*
|
||||||
|
* @param scriptInfoTaskInfo 百度外呼话术任务临时表
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int insertScriptInfoTaskInfo(ScriptInfoTaskInfo scriptInfoTaskInfo);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
package com.xinelu.manage.service.aibo;
|
||||||
|
|
||||||
|
import com.xinelu.manage.dto.aibo.CreateTaskDto;
|
||||||
|
import com.xinelu.manage.dto.aibo.ImportTaskDto;
|
||||||
|
import com.xinelu.manage.dto.aibo.TaskCallbackDataDto;
|
||||||
|
import com.xinelu.manage.vo.aibo.ImportTaskVo;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 百度客悦·智能外呼平台Service接口
|
||||||
|
*
|
||||||
|
* @author: haown
|
||||||
|
* @create: 2024-08-22 09:50
|
||||||
|
*/
|
||||||
|
public interface IAIOBService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取外呼平台accessToken
|
||||||
|
* @return 智能外呼平台 accessToken
|
||||||
|
* @Author haown
|
||||||
|
* @Date 2024-8-22 15:30
|
||||||
|
*/
|
||||||
|
String getAccessToken();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 创建任务
|
||||||
|
* @param createTaskDto 创建任务传输对象
|
||||||
|
* @return taskId 客悦·智能外呼平台任务唯一标识
|
||||||
|
* @Author haown
|
||||||
|
* @Date 2024-8-22 15:34
|
||||||
|
*/
|
||||||
|
String createTask(CreateTaskDto createTaskDto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 任务状态变更
|
||||||
|
* @param taskId 任务id
|
||||||
|
* @param taskStatus 修改状态 2:执行中,3:已暂停,4:已完成(如点击「终止」
|
||||||
|
* @return 状态码
|
||||||
|
* @Author haown
|
||||||
|
* @Date 2024-8-23 11:49
|
||||||
|
*/
|
||||||
|
Integer updateTaskStatus(String taskId, Integer taskStatus);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 任务导入客户名单
|
||||||
|
* @param importTaskDto 导入名单传输对象
|
||||||
|
* @return 名单导入结果
|
||||||
|
* @Author haown
|
||||||
|
* @Date 2024-8-23 17:34
|
||||||
|
*/
|
||||||
|
List<ImportTaskVo> importTask(ImportTaskDto importTaskDto);
|
||||||
|
|
||||||
|
String taskCallBack(Integer callbackType, TaskCallbackDataDto data);
|
||||||
|
}
|
||||||
@ -0,0 +1,227 @@
|
|||||||
|
package com.xinelu.manage.service.aibo.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.xinelu.common.core.redis.RedisCache;
|
||||||
|
import com.xinelu.common.exception.ServiceException;
|
||||||
|
import com.xinelu.common.utils.StringUtils;
|
||||||
|
import com.xinelu.manage.dto.aibo.CreateTaskDto;
|
||||||
|
import com.xinelu.manage.dto.aibo.ImportTaskDto;
|
||||||
|
import com.xinelu.manage.dto.aibo.TaskCallbackDataDto;
|
||||||
|
import com.xinelu.manage.service.aibo.IAIOBService;
|
||||||
|
import com.xinelu.manage.vo.aibo.ImportTaskVo;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 百度客悦·智能外呼平台Service实现
|
||||||
|
* @author: haown
|
||||||
|
* @create: 2024-08-22 09:54
|
||||||
|
**/
|
||||||
|
@Service
|
||||||
|
public class AIOBServiceImpl implements IAIOBService {
|
||||||
|
@Value("${aiob.url}")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Value("${aiob.accessKey}")
|
||||||
|
private String accessKey;
|
||||||
|
|
||||||
|
@Value("${aiob.secretKey}")
|
||||||
|
private String secretKey;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisCache redisCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取外呼平台accessToken
|
||||||
|
* @return 智能外呼平台 accessToken
|
||||||
|
* @Author haown
|
||||||
|
* @Date 2024-8-22 15:30
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getAccessToken() {
|
||||||
|
String accessToken = redisCache.getCacheObject("AIOBAssessToken");
|
||||||
|
if (StringUtils.isBlank(accessToken)) {
|
||||||
|
JSONObject requestBodyJson = new JSONObject();
|
||||||
|
requestBodyJson.put("secretKey", secretKey);
|
||||||
|
requestBodyJson.put("accessKey", accessKey);
|
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
HttpEntity<JSONObject> requestEntity = new HttpEntity<>(requestBodyJson, headers);
|
||||||
|
|
||||||
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
|
ResponseEntity<String> responseEntity = restTemplate.exchange(url + "/v2/getToken", HttpMethod.POST, requestEntity, String.class);
|
||||||
|
JSONObject object = JSON.parseObject(responseEntity.getBody());
|
||||||
|
if (object == null || object.getInteger("code") == null || object.getInteger("code") != 200) {
|
||||||
|
throw new ServiceException("获取accessToken失败!");
|
||||||
|
}
|
||||||
|
JSONObject data = object.getJSONObject("data");
|
||||||
|
// accessToken放入redis缓存
|
||||||
|
accessToken = data.getString("accessToken");
|
||||||
|
// 有效期30天
|
||||||
|
int expires_in = object.getInteger("expires_in");
|
||||||
|
redisCache.setCacheObject("AIOBAssessToken", accessToken, expires_in, TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
|
return accessToken;
|
||||||
|
//{
|
||||||
|
// "time" : 1724293180993,
|
||||||
|
// "code" : 200,
|
||||||
|
// "msg" : "OK",
|
||||||
|
// "data" : {
|
||||||
|
// "tenantId" : 3849515568332800,
|
||||||
|
// "accessToken" : "cc-api-auth-v2/10.B88F964FF8AEF605D75872F1B0EDFE57B28609A057F5E24104B4A7FB74CD63EC8199731D637E6EDFD195A82D5DFF454E",
|
||||||
|
// "expiresTime" : 43200,
|
||||||
|
// "accessKey" : "b6d2d73cdf2d4d7ca2ccc84968accdb3",
|
||||||
|
// "secretKey" : "9262d2fe32544eaabce18331bd5ca2c5"
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 创建任务
|
||||||
|
* @param createTaskDto 创建任务传输对象
|
||||||
|
* @return taskId 客悦·智能外呼平台任务唯一标识
|
||||||
|
* @Author haown
|
||||||
|
* @Date 2024-8-22 15:34
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String createTask(CreateTaskDto createTaskDto) {
|
||||||
|
String accessToken = getAccessToken();
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
headers.set("Authorization", accessToken);
|
||||||
|
|
||||||
|
HttpEntity<JSONObject> requestEntity = new HttpEntity<>((JSONObject)JSON.toJSON(createTaskDto), headers);
|
||||||
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
|
ResponseEntity<String> responseEntity = restTemplate.exchange(url + "/v3/console/apitask/create", HttpMethod.POST, requestEntity, String.class);
|
||||||
|
JSONObject object = JSON.parseObject(responseEntity.getBody());
|
||||||
|
if (object == null || object.getInteger("code") == null || object.getInteger("code") != 200) {
|
||||||
|
throw new ServiceException("创建任务失败," + object.getString("msg"));
|
||||||
|
}
|
||||||
|
JSONObject data = object.getJSONObject("data");
|
||||||
|
return data.getString("taskId");
|
||||||
|
// {
|
||||||
|
// "code": 200,
|
||||||
|
// "msg": "success",
|
||||||
|
// "data": {
|
||||||
|
// "taskId": "731346584781056" //任务ID,必填
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 任务状态变更
|
||||||
|
* @param taskId 任务id
|
||||||
|
* @param taskStatus 修改状态 2:执行中,3:已暂停,4:已完成(如点击「终止」
|
||||||
|
* @return 状态码
|
||||||
|
* @Author haown
|
||||||
|
* @Date 2024-8-23 11:49
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Integer updateTaskStatus(String taskId, Integer taskStatus) {
|
||||||
|
String accessToken = getAccessToken();
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
headers.set("Authorization", accessToken);
|
||||||
|
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.fluentPut("taskId", taskId)
|
||||||
|
.fluentPut("taskStatus", taskStatus);
|
||||||
|
HttpEntity<JSONObject> requestEntity = new HttpEntity<>(jsonObject, headers);
|
||||||
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
|
ResponseEntity<String> responseEntity = restTemplate.exchange(url + "/v3/console/realtime/status/create", HttpMethod.POST, requestEntity, String.class);
|
||||||
|
JSONObject object = JSON.parseObject(responseEntity.getBody());
|
||||||
|
if (object == null || object.getInteger("code") == null || object.getInteger("code") != 200) {
|
||||||
|
throw new ServiceException("修改任务状态失败," + object.getString("msg"));
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
// {
|
||||||
|
// "requestId": "c323dc9e5f67427c9c9d735a76e14164",
|
||||||
|
// "time": 1724375025670,
|
||||||
|
// "code": 200,
|
||||||
|
// "msg": "OK",
|
||||||
|
// "data": null
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 任务导入客户名单
|
||||||
|
* @param importTaskDto 导入名单传输对象
|
||||||
|
* @return 名单导入结果
|
||||||
|
* @Author haown
|
||||||
|
* @Date 2024-8-23 17:34
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<ImportTaskVo> importTask(ImportTaskDto importTaskDto) {
|
||||||
|
String accessToken = getAccessToken();
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
headers.set("Authorization", accessToken);
|
||||||
|
|
||||||
|
HttpEntity<JSONObject> requestEntity = new HttpEntity<>((JSONObject)JSON.toJSON(importTaskDto), headers);
|
||||||
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
|
ResponseEntity<String> responseEntity = restTemplate.exchange(url + "/v3/console/apitask/import", HttpMethod.POST, requestEntity, String.class);
|
||||||
|
JSONObject object = JSON.parseObject(responseEntity.getBody());
|
||||||
|
if (object == null || object.getInteger("code") == null || object.getInteger("code") != 200) {
|
||||||
|
throw new ServiceException("导入名单失败," + object.getString("msg"));
|
||||||
|
}
|
||||||
|
JSONObject data = object.getJSONObject("data");
|
||||||
|
|
||||||
|
JSONArray resList = data.getJSONArray("retList");
|
||||||
|
List<ImportTaskVo> importTaskList = Arrays.asList(resList.toArray(ImportTaskVo.class));
|
||||||
|
return importTaskList;
|
||||||
|
// {
|
||||||
|
// "code": 200,
|
||||||
|
// "msg": "success",
|
||||||
|
// "data": {
|
||||||
|
// "successNum": 2, // 名单导入成功条数
|
||||||
|
// "failedNum": 0, // 名单导入失败条数
|
||||||
|
// "resList": [ // 导入明细
|
||||||
|
// {
|
||||||
|
// "status": true, // 导入的状态,true为 成功 bool
|
||||||
|
// "extJson": "",//调用方的业务随路数据, 字符串,百度侧原文回传
|
||||||
|
// "reason": null, // 失败原因
|
||||||
|
// "taskMemberId": 734116037099777 // 百度侧memberID,用户 用户号码组详情查询
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "status": true,
|
||||||
|
// "extJson": "",//调用方的业务随路数据, 字符串,百度侧原文回传
|
||||||
|
// "reason": null,
|
||||||
|
// "taskMemberId": 734116037116160
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String taskCallBack(Integer callbackType, TaskCallbackDataDto data) {
|
||||||
|
//TaskCallbackDataDto(sessionId=3874887150206976_2e1ae4e5ee0a4513b61d2411523f7b9b, tenantId=3849515568332800,
|
||||||
|
// taskId=3874887150206976, taskName=测试20240829, robotId=11a05202-12a4-437a-b989-43235b920a2f,
|
||||||
|
// robotName=慢病用药回访, memberId=3875110220070912, mobile=15166940975, callTimes=1,
|
||||||
|
// callerNum=02110001062, endType=1, callType=0, endTypeReason=null, contactUUID=1724917686303674_278162,
|
||||||
|
// field=null, collectInfo={},
|
||||||
|
// record=[{"role":"speech","timestamp":1724917698521,"contextText":"您好,我是山东省立医院的电话客服,请问您是李四本人或家属吗?", "sn":"19a09431-1ac6-43a1-8f9f-4b6f617bed73","intent":"NOINTENT","start":"00:00.033","stop":"00:06.974","timeLen":6941,"interrupted":false,"silent":false,"nodeInfo":"eyJwcm9jZXNzTmFtZSI6IuaFoueXheeUqOiNr+Wbnuiuv+ivneacryIsIm5vZGVOYW1lIjoi5byA5Zy655m96IqC54K5X3RwcnZtc2g4IiwiaW50ZW50IjoiIiwiZW50aXR5IjpbXSwic3lzdGVtRXZlbnQiOiIiLCJmYXEiOiIifQ=="},
|
||||||
|
// {"role":"voice","timestamp":1724917707542,"content":"是的","contextText":"是的","sn":"0e5c9c4e65db11ef_2_1","start":"00:06.930","stop":"00:08.330","timeLen":1400,"interrupted":false,"silent":false},
|
||||||
|
// {"role":"speech","timestamp":1724917708359,"content":"是的","contextText":"好的,您之前在我们医院住过院,想了解一下您近期的健康状况。","sn":"0e5c9c4e65db11ef_2_1","intent":"patient_self","start":"00:09.871","stop":"00:15.793","timeLen":5922,"interrupted":false,"silent":false,"nodeInfo":"eyJwcm9jZXNzTmFtZSI6IuaFoueXheeUqOiNr+Wbnuiuv+ivneacryIsIm5vZGVOYW1lIjoi5pys5Lq66IqC54K5X3Nyd2Q5MTR3IiwiaW50ZW50Ijoi5piv5pys5Lq6IiwiZW50aXR5IjpbXSwic3lzdGVtRXZlbnQiOiIiLCJmYXEiOiIifQ=="},
|
||||||
|
// {"role":"voice","timestamp":1724917718191,"content":"好的嗯","contextText":"好的嗯","sn":"0e5c9c4e65db11ef_4_1","start":"00:16.650","stop":"00:18.970","timeLen":2320,"interrupted":false,"silent":false},
|
||||||
|
// {"role":"speech","timestamp":1724917718873,"content":"好的嗯","contextText":"您是否正常按时服药呢?","sn":"0e5c9c4e65db11ef_4_1","intent":"NOINTENT","start":"00:20.385","stop":"00:22.917","timeLen":2532,"interrupted":false,"silent":false,"nodeInfo":"eyJwcm9jZXNzTmFtZSI6IuaFoueXheeUqOiNr+Wbnuiuv+ivneacryIsIm5vZGVOYW1lIjoi6IKv5a6a6IqC54K5X3F6aWpzb2g2IiwiaW50ZW50IjoiIiwiZW50aXR5IjpbXSwic3lzdGVtRXZlbnQiOiIiLCJmYXEiOiIifQ=="},
|
||||||
|
// {"role":"voice","timestamp":1724917725425,"content":"是的","contextText":"是的","sn":"0e5c9c4e65db11ef_6_1","start":"00:24.810","stop":"00:26.210","timeLen":1400,"interrupted":false,"silent":false},
|
||||||
|
// {"role":"speech","timestamp":1724917725993,"content":"是的","contextText":"祝您早日康复。","sn":"0e5c9c4e65db11ef_6_1","intent":"sys_yes","start":"00:27.505","stop":"00:29.637","timeLen":2132,"interrupted":false,"silent":false,"nodeInfo":"eyJwcm9jZXNzTmFtZSI6IuaFoueXheeUqOiNr+Wbnuiuv+ivneacryIsIm5vZGVOYW1lIjoi5oyJ5pe25pyN6I2v6IqC54K5X3Bxd2RkcDBpIiwiaW50ZW50Ijoi6IKv5a6a5oSP5Zu+IiwiZW50aXR5IjpbXSwic3lzdGVtRXZlbnQiOiIiLCJmYXEiOiIifQ=="}],
|
||||||
|
// durationTimeLen=42, ringingTimeLen=9, talkingTimeLen=29, startTime=1724917686000, ringStartTime=1724917688000, talkingStartTime=1724917698000, endTime=1724917728000, intent=null, action=[HANGUP], isRobotHangup=true,
|
||||||
|
// dialogVar={"departmentName":"山东省立医院","patientName":"李四"}, smsVar=null, extJson=测试2, transResult=0)
|
||||||
|
return data.getTaskId();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.xinelu.manage.vo.aibo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 导入任务名单返回视图类
|
||||||
|
* @author: haown
|
||||||
|
* @create: 2024-08-23 16:19
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
public class ImportTaskVo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入的状态,true为 成功
|
||||||
|
*/
|
||||||
|
private Boolean status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用方的业务随路数据, 字符串,百度侧原文回传
|
||||||
|
*/
|
||||||
|
private String extJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 失败原因
|
||||||
|
*/
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 百度侧memberID,用户 用户号码组详情查询
|
||||||
|
*/
|
||||||
|
private Integer taskMemberId;
|
||||||
|
}
|
||||||
@ -26,6 +26,7 @@
|
|||||||
<result property="updateBy" column="update_by"/>
|
<result property="updateBy" column="update_by"/>
|
||||||
<result property="updateTime" column="update_time"/>
|
<result property="updateTime" column="update_time"/>
|
||||||
<result property="robotPublishId" column="robot_publish_id"/>
|
<result property="robotPublishId" column="robot_publish_id"/>
|
||||||
|
<result property="variables" column="variables"/>
|
||||||
|
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
@ -56,7 +57,8 @@
|
|||||||
create_time,
|
create_time,
|
||||||
update_by,
|
update_by,
|
||||||
update_time,
|
update_time,
|
||||||
robot_publish_id
|
robot_publish_id,
|
||||||
|
variables
|
||||||
from script_info
|
from script_info
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
@ -80,7 +82,8 @@
|
|||||||
si.create_time,
|
si.create_time,
|
||||||
si.update_by,
|
si.update_by,
|
||||||
si.update_time,
|
si.update_time,
|
||||||
si.robot_publish_id
|
si.robot_publish_id,
|
||||||
|
si.variables
|
||||||
from script_info si
|
from script_info si
|
||||||
left join department d on d.id = si.department_id
|
left join department d on d.id = si.department_id
|
||||||
<where>
|
<where>
|
||||||
@ -200,6 +203,8 @@
|
|||||||
</if>
|
</if>
|
||||||
<if test="robotPublishId != null">robot_publish_id,
|
<if test="robotPublishId != null">robot_publish_id,
|
||||||
</if>
|
</if>
|
||||||
|
<if test="variables != null">variables,
|
||||||
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
<if test="departmentId != null">#{departmentId},
|
<if test="departmentId != null">#{departmentId},
|
||||||
@ -242,6 +247,8 @@
|
|||||||
</if>
|
</if>
|
||||||
<if test="robotPublishId != null">#{robotPublishId},
|
<if test="robotPublishId != null">#{robotPublishId},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="variables != null">#{variables},
|
||||||
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
@ -304,6 +311,9 @@
|
|||||||
<if test="robotPublishId != null">robot_publish_id =
|
<if test="robotPublishId != null">robot_publish_id =
|
||||||
#{robotPublishId},
|
#{robotPublishId},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="variables != null">variables =
|
||||||
|
#{variables},
|
||||||
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|||||||
@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.xinelu.manage.mapper.scriptinfotaskinfo.ScriptInfoTaskInfoMapper">
|
||||||
|
|
||||||
|
<resultMap type="ScriptInfoTaskInfo" id="ScriptInfoTaskInfoResult">
|
||||||
|
<result property="id" column="id"/>
|
||||||
|
<result property="scriptInfoId" column="script_info_id"/>
|
||||||
|
<result property="robotId" column="robot_id"/>
|
||||||
|
<result property="taskId" column="task_id"/>
|
||||||
|
<result property="createTime" column="create_time"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectScriptInfoTaskInfoVo">
|
||||||
|
select id,
|
||||||
|
script_info_id,
|
||||||
|
robot_id,
|
||||||
|
task_id,
|
||||||
|
create_time,
|
||||||
|
from script_info_task_info
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="getByScriptInfoId" resultType="java.lang.String">
|
||||||
|
select task_id
|
||||||
|
from script_info_task_info
|
||||||
|
where script_info_id = #{scriptInfoId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertScriptInfoTaskInfo" parameterType="ScriptInfoTaskInfo" useGeneratedKeys="true"
|
||||||
|
keyProperty="id">
|
||||||
|
insert into script_info_task_info
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="scriptInfoId != null">script_info_id,
|
||||||
|
</if>
|
||||||
|
<if test="robotId != null">robot_id,
|
||||||
|
</if>
|
||||||
|
<if test="taskId != null">task_id,
|
||||||
|
</if>
|
||||||
|
<if test="createTime != null">create_time,
|
||||||
|
</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="scriptInfoId != null">#{scriptInfoId},
|
||||||
|
</if>
|
||||||
|
<if test="robotId != null">#{robotId},
|
||||||
|
</if>
|
||||||
|
<if test="taskId != null">#{taskId},
|
||||||
|
</if>
|
||||||
|
<if test="createTime != null">#{createTime},
|
||||||
|
</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
</mapper>
|
||||||
@ -1,26 +1,45 @@
|
|||||||
package com.xinelu.quartz.task;
|
package com.xinelu.quartz.task;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.xinelu.common.enums.NodeExecuteStatusEnum;
|
import com.xinelu.common.enums.NodeExecuteStatusEnum;
|
||||||
import com.xinelu.common.enums.PhoneDialMethodEnum;
|
import com.xinelu.common.enums.PhoneDialMethodEnum;
|
||||||
import com.xinelu.common.enums.TaskNodeTypeEnum;
|
import com.xinelu.common.enums.TaskNodeTypeEnum;
|
||||||
|
import com.xinelu.common.utils.StringUtils;
|
||||||
|
import com.xinelu.manage.domain.patientinfo.PatientInfo;
|
||||||
import com.xinelu.manage.domain.patientvisitrecord.PatientVisitRecord;
|
import com.xinelu.manage.domain.patientvisitrecord.PatientVisitRecord;
|
||||||
|
import com.xinelu.manage.domain.scriptInfo.ScriptInfo;
|
||||||
|
import com.xinelu.manage.domain.scriptinfotaskinfo.ScriptInfoTaskInfo;
|
||||||
import com.xinelu.manage.domain.signpatientmanageroute.SignPatientManageRoute;
|
import com.xinelu.manage.domain.signpatientmanageroute.SignPatientManageRoute;
|
||||||
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
|
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
|
||||||
import com.xinelu.manage.domain.signpatientrecord.SignPatientRecord;
|
import com.xinelu.manage.domain.signpatientrecord.SignPatientRecord;
|
||||||
|
import com.xinelu.manage.dto.aibo.CreateTaskDto;
|
||||||
|
import com.xinelu.manage.dto.aibo.CustomerInfoDto;
|
||||||
|
import com.xinelu.manage.dto.aibo.ImportTaskDto;
|
||||||
import com.xinelu.manage.dto.signpatientmanageroutenode.SignPatientManageRouteNodeDto;
|
import com.xinelu.manage.dto.signpatientmanageroutenode.SignPatientManageRouteNodeDto;
|
||||||
|
import com.xinelu.manage.mapper.labelfieldcontent.LabelFieldContentMapper;
|
||||||
|
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
|
||||||
import com.xinelu.manage.mapper.patientvisitrecord.PatientVisitRecordMapper;
|
import com.xinelu.manage.mapper.patientvisitrecord.PatientVisitRecordMapper;
|
||||||
|
import com.xinelu.manage.mapper.scriptInfo.ScriptInfoMapper;
|
||||||
|
import com.xinelu.manage.mapper.scriptinfotaskinfo.ScriptInfoTaskInfoMapper;
|
||||||
import com.xinelu.manage.mapper.signpatientmanageroute.SignPatientManageRouteMapper;
|
import com.xinelu.manage.mapper.signpatientmanageroute.SignPatientManageRouteMapper;
|
||||||
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
|
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
|
||||||
import com.xinelu.manage.mapper.signpatientrecord.SignPatientRecordMapper;
|
import com.xinelu.manage.mapper.signpatientrecord.SignPatientRecordMapper;
|
||||||
import com.xinelu.manage.service.signpatientmanageroutenode.IRobotPublishService;
|
import com.xinelu.manage.service.aibo.IAIOBService;
|
||||||
import com.xinelu.manage.service.signpatientmanageroutenode.ISignPatientManageRouteNodeService;
|
import com.xinelu.manage.service.signpatientmanageroutenode.ISignPatientManageRouteNodeService;
|
||||||
|
import com.xinelu.manage.vo.labelfieldcontent.LabelFieldInfoContentVo;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,10 +62,20 @@ public class UploadRobotPublishTask {
|
|||||||
@Resource
|
@Resource
|
||||||
private PatientVisitRecordMapper patientVisitRecordMapper;
|
private PatientVisitRecordMapper patientVisitRecordMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private IRobotPublishService robotPublishService;
|
private ScriptInfoTaskInfoMapper scriptInfoTaskInfoMapper;
|
||||||
|
@Resource
|
||||||
|
private IAIOBService aiobService;
|
||||||
|
@Resource
|
||||||
|
private ScriptInfoMapper scriptInfoMapper;
|
||||||
|
@Resource
|
||||||
|
private PatientInfoMapper patientInfoMapper;
|
||||||
|
@Resource
|
||||||
|
private LabelFieldContentMapper labelFieldContentMapper;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void uploadRobotPublishTask() {
|
public void uploadRobotPublishTask() {
|
||||||
log.info("开始执行爱医声上传任务定时任务......");
|
log.info("开始执行百度智能外呼创建任务定时任务......");
|
||||||
// 查找需要当天执行的AI打电话任务
|
// 查找需要当天执行的AI打电话任务
|
||||||
SignPatientManageRouteNodeDto signPatientManageRouteNodeDto = new SignPatientManageRouteNodeDto();
|
SignPatientManageRouteNodeDto signPatientManageRouteNodeDto = new SignPatientManageRouteNodeDto();
|
||||||
signPatientManageRouteNodeDto.setTaskNodeType(TaskNodeTypeEnum.PHONE_OUTBOUND.getInfo());
|
signPatientManageRouteNodeDto.setTaskNodeType(TaskNodeTypeEnum.PHONE_OUTBOUND.getInfo());
|
||||||
@ -65,7 +94,98 @@ public class UploadRobotPublishTask {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (CollectionUtils.isNotEmpty(executeNodeList)) {
|
if (CollectionUtils.isNotEmpty(executeNodeList)) {
|
||||||
|
// 按照话术id分组,每个话术id对应不同的机器人id, 每个机器人每天创建一条任务
|
||||||
|
Map<Long, List<SignPatientManageRouteNode>> groupByScriptInfo = executeNodeList.stream().collect(Collectors.groupingBy(SignPatientManageRouteNode::getScriptInfoId));
|
||||||
|
// 根据机器人id查询智能外呼系统的任务id
|
||||||
|
for (Long scriptInfoId : groupByScriptInfo.keySet()) {
|
||||||
|
ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(scriptInfoId);
|
||||||
|
String taskId = scriptInfoTaskInfoMapper.getByScriptInfoId(scriptInfoId);
|
||||||
|
if (StringUtils.isBlank(taskId)) {
|
||||||
|
// 没有任务则创建任务
|
||||||
|
if (ObjectUtils.isNotEmpty(scriptInfo)) {
|
||||||
|
CreateTaskDto createTaskDto = new CreateTaskDto();
|
||||||
|
createTaskDto.setTaskName(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + scriptInfo.getScriptName());
|
||||||
|
createTaskDto.setRobotId(scriptInfo.getRobotPublishId());
|
||||||
|
createTaskDto.setDialStartDate(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
||||||
|
createTaskDto.setDialEndDate(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
||||||
|
createTaskDto.setForbidDialDate(Arrays.asList(99));
|
||||||
|
createTaskDto.setNumTypeFilterList(Arrays.asList(1,2));
|
||||||
|
taskId = aiobService.createTask(createTaskDto);
|
||||||
|
|
||||||
|
ScriptInfoTaskInfo scriptInfoTaskInfo = new ScriptInfoTaskInfo();
|
||||||
|
scriptInfoTaskInfo.setScriptInfoId(scriptInfoId);
|
||||||
|
scriptInfoTaskInfo.setTaskId(taskId);
|
||||||
|
scriptInfoTaskInfo.setRobotId(scriptInfo.getRobotPublishId());
|
||||||
|
scriptInfoTaskInfo.setCreateTime(LocalDateTime.now());
|
||||||
|
scriptInfoTaskInfoMapper.insertScriptInfoTaskInfo(scriptInfoTaskInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 客户名单list
|
||||||
|
List<SignPatientManageRouteNode> scriptNodeList = groupByScriptInfo.get(scriptInfoId);
|
||||||
|
List<CustomerInfoDto> customerInfoList = new ArrayList<>();
|
||||||
|
scriptNodeList.forEach(node -> {
|
||||||
|
CustomerInfoDto customerInfoDto = new CustomerInfoDto();
|
||||||
|
customerInfoDto.setExtJson(node.getId() + "");
|
||||||
|
SignPatientManageRoute signPatientManageRoute = signPatientManageRouteMapper.selectSignPatientManageRouteById(node.getManageRouteId());
|
||||||
|
PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(signPatientManageRoute.getPatientId());
|
||||||
|
customerInfoDto.setMobile(patientInfo.getPatientPhone());
|
||||||
|
// 查询患者画像信息
|
||||||
|
List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(patientInfo.getId());
|
||||||
|
// 处理变量
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
if (StringUtils.isNotBlank(scriptInfo.getVariables())) {
|
||||||
|
List<String> variables = Arrays.asList(scriptInfo.getVariables().split("|"));
|
||||||
|
variables.forEach(variable -> {
|
||||||
|
LabelFieldInfoContentVo labelFieldContent = labelFieldContentList.stream().filter(s -> Objects.equals(s.getFieldCode(), variable.replaceAll("_", "").toUpperCase())).findFirst().orElse(null);
|
||||||
|
jsonObject.fluentPut(variable, ObjectUtils.isEmpty(labelFieldContent) ? "" : labelFieldContent.getFieldValue());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
customerInfoDto.setVar(jsonObject);
|
||||||
|
customerInfoList.add(customerInfoDto);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 上传名单
|
||||||
|
ImportTaskDto importTaskDto = new ImportTaskDto();
|
||||||
|
importTaskDto.setTaskId(taskId);
|
||||||
|
importTaskDto.setSecretType(2);
|
||||||
|
importTaskDto.setCustomerInfoList(customerInfoList);
|
||||||
|
aiobService.importTask(importTaskDto);
|
||||||
|
|
||||||
|
// 开启任务
|
||||||
|
aiobService.updateTaskStatus(taskId, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开启任务
|
||||||
//robotPublishService.uploadRobotPublishTask(executeNodeList);
|
//robotPublishService.uploadRobotPublishTask(executeNodeList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String convertToCamelCase(String s) {
|
||||||
|
if (s == null || !s.contains("_")){
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
//用来判断大写的标志
|
||||||
|
boolean nextUpperCase = false;
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
if ("_".equals(String.valueOf(s.charAt(i)))) {
|
||||||
|
nextUpperCase = true;
|
||||||
|
} else {
|
||||||
|
if (nextUpperCase) {
|
||||||
|
sb = sb.append(String.valueOf(s.charAt(i)).toUpperCase());
|
||||||
|
nextUpperCase = false;
|
||||||
|
}else {
|
||||||
|
sb = sb.append(s.charAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String underscoreCase = "user_name";
|
||||||
|
String camelCase = convertToCamelCase(underscoreCase);
|
||||||
|
System.out.println(camelCase); // 输出 "UserName"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user