使用easyswoole 框架开发的 新一代电话机器人开源PHP源码
项目地址:https://gitee.com/ddrjcode/robotphp
- 代理商页面演示地址
http://119.23.229.15:8080
用户名:c0508
密码:123456
包含 AI外呼管理,话术管理,CRM管理,坐席管理等功能。
- 管理员后台演示地址
http://119.23.229.15
用户名:admin
密码:123456
包含 线路管理,代理商管理等功能
AI外呼管理截图
话术管理截图
坐席页面
管理员页面
线路管理
机器人话术代码:
<?php
/**
* Created by PhpStorm.
* User: WIN10
* Date: 2021/12/18
* Time: 16:04
*/
namespace App\Traits;
use App\Model\Speech\SpeechLabelSynonym;
use App\Model\Speech\SpeechNodeModel;
use App\Model\Speech\SpeechProcessModel;
use App\Model\Speech\SpeechProcessNodeSettingModel;
use App\Model\SpeechMul\SpeechMulLabelSynonym;
use App\Model\SpeechMul\SpeechMulProcessSettingModel;
trait SpeechExamineTrait{
//主流程匹配关键词结果数组
public function getResultSynonym($speechId)
{
$resultSynonym = [];
$synonymList = SpeechLabelSynonym::create()->getAll(["speech_id"=>$speechId]);
foreach ($synonymList as $val){
if(isset($val["sls_name"])) {
$resultSynonym[$val["node_id"]][$val["sls_keyword"]][] = $val["sls_name"];
}
}
return $resultSynonym;
}
//获取主流程的$nodesInfo信息 节点信息
//$processQueuesReal = []; //真实存在的主流程节点(只有节点才存在到这个主流程)
public function getNodesInfoList($where)
{
$nodesInfo = [];//所有节点信息map=>(k,v)
$processNodes = [];
$processQueuesReal = []; //真实存在的主流程节点(只有节点才存在到这个主流程)
//所有节点的信息
$nodesInfoList = SpeechNodeModel::create()->getAll($where);
foreach ($nodesInfoList as $kk=>$vv)
{
$nodesInfo[$vv["node_id"]] = $vv;
if(!isset($processNodes[$vv["process_id"]])){//真实存在
array_push($processQueuesReal,$vv["process_id"]);
}else{
$processNodes[$vv["process_id"]] = [];
}
}
return [$nodesInfo,$processQueuesReal];
}
//$processNodesArr 所有节点的数组
//$processQueues 所有的流程按照顺序
public function getProcessQueues($where)
{
$processNodesArr = [];
$processQueues = [];//所有的流程按照顺序
$processArray = SpeechProcessModel::create()->getAll($where,'process_id',["sort,process_id","ASC"]);
foreach ($processArray as $a=>$item){
array_push($processQueues,$item["process_id"]);
$processNodesArr[$item["process_id"]] = [];
}
return [$processNodesArr,$processQueues];
}
//所有的参数节点流程
public function getArgArray($where)
{
$argList = SpeechProcessNodeSettingModel::create()->getAll($where,"set_key,set_value,node_id");//所有的参数节点流程
$argArray = [];
foreach ($argList as $argK=>$argValue){
$argArray[$argValue["node_id"]][$argValue["set_key"]] = $argValue["set_value"];
}
return $argArray;
}
//获取所有树的第一个节点集
// $nodes = SpeechNodeTreeModel::create()->getAll($where,'process_id,node_id,parent_id,nodes_id',["node_id","ASC"]);
public function getTreeFirstNode($nodes)
{
$treeFirstNode = [];
foreach ($nodes as $key=>$value)
{
if($value["parent_id"]==0){
$treeFirstNode[$value["process_id"]] = $value;
}
}
return $treeFirstNode;
}
public function getMulTreeFirstNode($nodes)
{
$treeFirstNode = [];
foreach ($nodes as $key=>$value)
{
if($value["parent_id"]==0){
$treeFirstNode[$value["process_mul_id"]] = $value;
}
}
return $treeFirstNode;
}
//获取流程的节点的集
//$processNodesNode 子集
// $nodes = SpeechNodeTreeModel::create()->getAll($where,'process_id,node_id,parent_id,nodes_id',["node_id","ASC"]);
//$resultSynonym 主流程匹配关键词结果数组集
//$childParent 父子节点数组 $childParent = SpeechSmallNodeRelationModel::create()->getColumn($where,"node_id","small_node_id");
//$processReal 真实按照顺序的主流程
//$processRealFlip 主流程反转主流程
//$treeFirstNode 获取所有树的第一个节点集
//$nodeSynonymList 匹配的关键词
//$targetLabel
//$nodesInfo
public function getProcessNodesNode($nodes,$processNodesArr,$nodesInfo,$resultSynonym,$childParent,$processReal,$targetLabel,$processRealFlip,$treeFirstNode,$nodeSynonymList)
{
//判断是否有相同的节点
$sameNodeList = [];
$processNodesNode = [];
//用一个权重数组去获取最终值吧(始终取最大的)
$priorityArray = [];
foreach ($nodes as $key=>$value)
{
$valueProcessId = $value["process_id"];
$processNodesArr[$valueProcessId][] = $value;
$subFlowModel = [];
$valueNodesId = $value["nodes_id"];
$valueParentId = $value["parent_id"];
$valueNodeId = $value["node_id"];
$priority = "0"; //分支权重
if($valueNodesId) {
$word = $targetLabel[$valueNodesId]??"";
if ($word) {
$synonymCode = "W." . $word;
$yesSynonym = [];
$isMore = 0;
$arrSubFlow = [];
$synonymArray = [];
switch ($word){
case "肯定":
if(isset($resultSynonym[$childParent[$valueNodesId]]["yes"])) {
$yesSynonym = array_values($resultSynonym[$childParent[$valueNodesId]]["yes"]);
}
$priority = "5";
break;
case "否定":
if(isset($resultSynonym[$childParent[$valueNodesId]]["no"])) {
$yesSynonym = array_values($resultSynonym[$childParent[$valueNodesId]]["no"]);
}
$priority = "10";
break;
case "拒绝":
if(isset($resultSynonym[$childParent[$valueNodesId]]["reject"])) {
$yesSynonym = array_values($resultSynonym[$childParent[$valueNodesId]]["reject"]);
}
$priority = "12";
break;
case "默认":
$priority = "2";
$isMore = 1;
break;
}
if($isMore==0) {//不是默认
$synonymSystem = $yesSynonym ?: [$synonymCode];
foreach ($synonymSystem as $item){
$synonymArray[$item] = $word;
}
$arrSubFlow = [
"condition" => [
"text" => $synonymSystem
],
"priority" => $priority,
"description" => $word
];
}elseif($isMore==1){//是默认
$arrSubFlow = [
"condition" => [
"text" => ["any"]
],
"priority" => $priority,
"description" => $word
];
}
if(!isset($priorityArray[$valueNodeId])) {
$priorityArray[$valueNodeId] = $priority;
}else{
if($priorityArray[$valueNodeId]<$priority){
$priorityArray[$valueNodeId] = $priority;
}
}
if($nodesInfo[$valueNodeId]["info_talk_info"]) { //有信息的
if(!isset($sameNodeList[$valueProcessId][$valueParentId][$valueNodeId])) {//是否存在当前流程,当前父id的,节点id
//判断是否当前节点参数是否为空
$subFlowModel["F" . $valueNodeId] = $arrSubFlow;
if($isMore==0) {//不是默认
$nodeSynonymList[$valueNodeId] = $synonymArray;
}
$sameNodeList[$valueProcessId][$valueParentId][$valueNodeId] = $key+1;
}else{
if(!isset($processNodesNode[$valueProcessId][$valueParentId] ["F" . $valueNodeId]["condition"]["text"])) {
$processNodesNode[$valueProcessId][$valueParentId] ["F" . $valueNodeId]["condition"]["text"] = [];
}
if($isMore==0) {//非默认
//有text关键词的操作
if ($yesSynonym) {
$processNodesNode[$valueProcessId][$valueParentId] ["F" . $valueNodeId]["condition"]["text"] = array_merge($processNodesNode[$valueProcessId][$valueParentId] ["F" . $valueNodeId]["condition"]["text"] ,$yesSynonym);
}
//没有关键词的操作
if (!$yesSynonym) {
array_push($processNodesNode[$valueProcessId][$valueParentId] ["F" . $valueNodeId]["condition"]["text"], "W." . $word);
}
$nodeSynonymList[$valueNodeId] = array_merge($nodeSynonymList[$valueNodeId],$synonymArray);
}
if($isMore==1) {//默认
// $processNodesNode[$valueProcessId][$valueParentId] ["F" . $valueNodeId]["condition"]["text"]= ["any"];
array_push($processNodesNode[$valueProcessId][$valueParentId] ["F" . $valueNodeId]["condition"]["text"], "any");
}
if(!isset($processNodesNode[$valueProcessId][$valueParentId]["F" . $valueNodeId]["description"])) {
$processNodesNode[$valueProcessId][$valueParentId]["F" . $valueNodeId]["description"] = $word;
}else{
$processNodesNode[$valueProcessId][$valueParentId]["F" . $valueNodeId]["description"] .= "," . $word;
}
$processNodesNode[$valueProcessId][$valueParentId]["F" . $valueNodeId]["priority"] = $priorityArray[$valueNodeId];
}
}
elseif(!$nodesInfo[$valueNodeId]["info_talk_info"] && $nodesInfo[$valueNodeId]["type_id"]==2){
$next = $nodesInfo[$value["node_id"]]["next"]; //跳转的条件
$nextId = $nodesInfo[$value["node_id"]]["next_id"];//流程id
$process_id = $nodesInfo[$value["node_id"]]["process_id"]; //该流程id
[$resReturnData,$returnKey,$resReturn] = $this->checkNextFlow($next,$nextId,$process_id,$processReal,$processRealFlip,$treeFirstNode,$arrSubFlow);//没有信息的就是跳转信息
if(!isset($sameNodeList[$valueProcessId][$valueParentId][$returnKey])) {
//判断是否当前节点参数是否为空
// $subFlowModel["F".$returnKey] = $resReturn;
if($resReturn){
if(!isset($subFlowModel["F" . $returnKey]["condition"]["text"])) {
$subFlowModel["F" . $returnKey]["condition"]["text"] = [];
}
if($isMore==0) {//非默认
if ($yesSynonym) {
$subFlowModel["F" . $returnKey]["condition"]["text"] = array_merge($processNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"],$yesSynonym);
}
if (!$yesSynonym ) {
array_push($subFlowModel ["F" . $returnKey]["condition"]["text"], "W." . $word);
}
}
if($isMore==1) {//默认
// $subFlowModel ["F" . $returnKey]["condition"]["text"]= ["any"];
array_push($subFlowModel ["F" . $returnKey]["condition"]["text"], "any");
}
$subFlowModel["F" . $returnKey]["priority"] = $priorityArray[$valueNodeId];
}
$nodeSynonymList[$returnKey] = $synonymArray;
$sameNodeList[$valueProcessId][$valueParentId][$returnKey] = $key+1;
}else{
if(!isset($processNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"])) {
$processNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"] = [];
}
if($isMore==0) {//非默认
if ($yesSynonym) {
$processNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"] = array_merge($processNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"],$yesSynonym);
$nodeSynonymList[$returnKey] = array_merge($nodeSynonymList[$returnKey],$synonymArray);
}
if (!$yesSynonym ) {
array_push($processNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"], "W." . $word);
$nodeSynonymList[$returnKey] = array_merge($nodeSynonymList[$returnKey],$synonymArray);
}
}
if($isMore==1) {//默认
// $processNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"]= ["any"];
array_push($processNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"], "any");
}
if(isset($processNodesNode[$valueProcessId][$valueParentId]["F" . $returnKey]["description"])) {
$processNodesNode[$valueProcessId][$valueParentId]["F" . $returnKey]["description"] = $word;
}else{
$processNodesNode[$valueProcessId][$valueParentId]["F" . $returnKey]["description"] .= "," . $word;
}
$processNodesNode[$valueProcessId][$valueParentId]["F" . $returnKey]["priority"] = $priorityArray[$valueNodeId];
}
}
}
}
//是否存在当前的流程的process的id的,父id
//不存在就是直接把subFlow赋值给他
if (!isset($processNodesNode[$valueProcessId][$valueParentId])) {
$processNodesNode[$valueProcessId][$valueParentId] = $subFlowModel;
} else {
//存在就是数组连接一起
$processNodesNode[$valueProcessId][$valueParentId] = array_merge($processNodesNode[$valueProcessId][$valueParentId],$subFlowModel);
}
}
return [$processNodesArr,$processNodesNode,$nodeSynonymList];
}
//获取flow流程
//获取 $nodeSynonymList 匹配的关键词
//$firstNode
//第一个主流程节点
//$version 版本
//$processReal 真实按照顺序的主流程
//$processRealFlip 主流程反转主流程
//$treeFirstNode 获取所有树的第一个节点集
//$nodeSynonymList 匹配的关键词
//$targetLabel
//$nodesInfo
//$processNodesNode 子集
public function getFlowList($flow,$processNodesArr,$nodeSynonymList,$version,$nodesInfo,$processNodesNode,$processReal,$processRealFlip,$treeFirstNode,$argArray,$allNodeWavKey,$allSettingsKey,$priority){
$count = 0;
$firstNode = "";//第一个节点
foreach ($processNodesArr as $ke=>$ve){
foreach ($ve as $kkk=>$vvv){
$vvvNodeId = $vvv["node_id"];
if($count==0){
$flow["Start"] = [
'action'=>'start',
'position'=>[
"x"=>2489,
"y"=>72
],
"subflow"=>['F'.$vvvNodeId."_".$version=>new \stdClass()]
];
}
$count++;
$arg = [];
$arg["action"] = "cti_play_and_detect_speech";
if($count==1){
$firstNode = $vvvNodeId."_".$version;
}
//模式
$argM = $argArray[$vvvNodeId]["moshi"]??"1";
if(isset($allSettingsKey[$vvvNodeId]['interrupt']) && $allSettingsKey[$vvvNodeId]['interrupt']) {
$argM = "2";
}
$argLuZao = $argArray[$vvvNodeId]["luzao"]??"";
$argKaiShi = $argArray[$vvvNodeId]["kaishi"]??"";
$argTingZhi = $argArray[$vvvNodeId]["tingzhi"]??"";
$argDengDai = $argArray[$vvvNodeId]["dengdai"]??"";
$argZuiDa = $argArray[$vvvNodeId]["zuida"]??"";
$argCanShu = $argArray[$vvvNodeId]["canshu"]??"";
$argLuYin = $argArray[$vvvNodeId]["luyin"]??"";
//挂机不需要这些参数
if($nodesInfo[$vvvNodeId]['next']!=1) {
$arg["filter"] = [
"text" => "S",
"dtmf" => "none"
];
if ($priority == 1) {
$arg["kb_priority"] = 0;
} elseif ($priority == 2) {
$arg["kb_priority"] = 1;
}
$arg["timeoutplaybacks"] = [];
$arg["timeoutrepetition"] = "";
$arg["mismatchplaybacks"] = [];
$arg["mismatchrepetition"] = "1";
$arg["globalflow"] = [
"all"
];
}else{//挂机节点不起用asr
$argM = 0;
}
$arg["argument"] = "'$argM' '16' '' '$argLuZao' '' '$argKaiShi' '$argTingZhi' '$argDengDai' '$argZuiDa' '' '$argCanShu' '$argLuYin' '' ''";
$arg["position"] = [
"x"=>$nodesInfo[$vvvNodeId]["node_x"],
"y"=>$nodesInfo[$vvvNodeId]["node_y"]
];
$arg["description"] = $nodesInfo[$vvvNodeId]["info_title"];
if(isset($allNodeWavKey[$vvvNodeId]) && $allNodeWavKey[$vvvNodeId]) {
$arg["playbacks"] = [$allNodeWavKey[$vvvNodeId]];
}else{
$arg["playbacks"] = [$nodesInfo[$vvvNodeId]["info_talk_info"]];
}
$arg["kb"] = 'C1';
if(isset($processNodesNode[$vvv["process_id"]][$vvvNodeId])) {
$arg["subflow"] = $processNodesNode[$vvv["process_id"]][$vvvNodeId];
}else{
$next = $nodesInfo[$vvvNodeId]["next"]; //跳转的条件
$nextId = $nodesInfo[$vvvNodeId]["next_id"];//流程id
$processId = $nodesInfo[$vvvNodeId]["process_id"]; //该流程id
[$arg["subflow"],$returnKey,$resReturn] = $this->checkNextFlow($next,$nextId,$processId,$processReal,$processRealFlip,$treeFirstNode);
}
if($nodesInfo[$vvvNodeId]["info_talk_info"]) {//如果是跳转节点,没有输入声音就是不输入
if($count==1){
$vvvNodeId .= "_".$version;
}
$flow["F" . $vvvNodeId] = $arg;
}
}
}
return [$flow,$nodeSynonymList,$firstNode];
}
//生成一个挂机节点
public function addEndPoints($flow)
{
/**
* 生成一个挂机节点
*/
$endPointsArray = [
'action'=>'hangup',
'position'=>[
"x"=>67,
"y"=>33
]
];
$flow["F9999999999999999999"]=$endPointsArray;
return $flow;
}
//生成一个等待用户回答节点
public function addWaitPoints($flow)
{
/**
* 生成一个挂机节点
*/
$endWaitArray = [
'action'=>"cti_play_and_detect_speech",
"argument"=>"'1' '16' '' '' '' '' '' '' '' '' '' '' '' ''",
"position"=>[
"x"=>391833,
"y"=>2372
],
"playbacks"=>[],
"description"=>"",
"sourceflowdepth"=>"1",
"globalflow"=>[
"all"
],
"kb" => 'C1',
"kb_priority"=>2,
"condition"=> [
"complete"=> [],
"text"=> []
],
"timeoutrepetition"=>"",
"mismatchplaybacks"=> [],
"subflow"=>[]
];
$flow["F88888888888888888888"]=$endWaitArray;
// $flow["F66666666666666666666"]=[
// "action"=> "return",
// "position"=> [
// "x"=> 2263,
// "y"=> 492
// ]
// ];
return $flow;
}
//生成一个挂机播放节点
public function addHangUpPlayContent($flow,$nodeId,$playbacks)
{
$hangUpArray = [
'action'=>"cti_play_and_detect_speech",
"argument"=>"'0' '16' '' '' '' '' '' '' '' '' '' '' '' ''",
"position"=>[
"x"=>391833,
"y"=>2372
],
"playbacks"=>$playbacks,
"description"=>"",
"sourceflowdepth"=>"1",
"condition"=> [
"text"=> []
],
"mismatchplaybacks"=> [],
"subflow"=>[
"F9999999999999999999"=> [
"condition"=>[
"complete"=> [
"any"
],
],
]
]
];
$flow["F".$nodeId] = $hangUpArray;
return $flow;
}
//生成一个挂机播放节点
public function addHangUpPlay($flow)
{
$hangUpArray = [
'action'=>"cti_play_and_detect_speech",
"argument"=>"'0' '16' '' '' '' '' '' '' '' '' '' '' '' ''",
"position"=>[
"x"=>391833,
"y"=>2372
],
"playbacks"=>[],
"description"=>"",
"sourceflowdepth"=>"1",
"condition"=> [
"text"=> []
],
"mismatchplaybacks"=> [],
"subflow"=>[
"F9999999999999999999"=> [
"condition"=>[
"text"=> [
"any"
],
],
]
]
];
$flow["F5555555555555555555555"] = $hangUpArray;
return $flow;
}
public function addWaitSubPoints(){
return [
"F9999999999999999999"=> [
"condition"=>[
"complete"=> [
"timeout()"
]
],
"description"=> "静音挂断"
],
"F66666666666666666666"=>[
"condition"=> [
"complete"=> [],
"text"=> [
"F.+"
]
],
"description"=> "有声音返回"
]
];
}
//生成一个挂机节点
public function addHangUpPoints()
{
$endPointsArray["F9999999999999999999"] = [
'condition'=>[
'complete'=> [
"any"
]
],
];
return $endPointsArray;
}
//跳转到指定主流程
public function toMainFlow($flowId)
{
$arg["F".$flowId]= [
"condition"=>[
"complete"=> [],
"text"=>[
"any"
],
"description"=>""
]
];
return $arg;
}
//跳转到指定多伦会话
public function toMulFlow($flowId)
{
$arg["F".$flowId."_".$flowId]= [
"condition"=>[
"complete"=> [],
"text"=>[
"any"
],
"description"=>""
]
];
return $arg;
}
//判断主流程下个流程的节点
public function checkNextFlow($next,$nextId,$process_id,$processReal,$processRealFlip,$treeFirstNode,$arrSubFlow=[])
{
$array = [];
$keyNext = $processRealFlip[$process_id]+1;//下一个next
$hangUp = $arrSubFlow?:["description"=>"无效回答", "condition"=>["text"=>["any"]]];
$nextProcess = $arrSubFlow?: ["condition" => ["text" => ["any"]], "description" => "跳转下一个流程"];
$keyReturn = "";
$resReturn = "";
switch ($next)
{
case 0:
case 2:
if(isset($processReal[$keyNext])){
$array["F" . $treeFirstNode[$processReal[$keyNext]]["node_id"]] = $nextProcess;
$keyReturn = $treeFirstNode[$processReal[$keyNext]]["node_id"];
$resReturn = $nextProcess;
}else{
$array["F9999999999999999999"] = $hangUp;
$keyReturn = "9999999999999999999";
$resReturn = $hangUp;
}
break;
case 1:
$array["F9999999999999999999"] = $hangUp;
$keyReturn = "9999999999999999999";
$resReturn = $hangUp;
break;
case 3:
if(isset($treeFirstNode[$nextId])) {
$fistNode = $treeFirstNode[$nextId];
$array["F" . $fistNode["node_id"]] = $nextProcess;
$keyReturn = $fistNode["node_id"];
$resReturn = $nextProcess;
}else{
$array["F9999999999999999999"] = $hangUp;
$keyReturn = "9999999999999999999";
$resReturn = $hangUp;
}
break;
case 4://返回接口
$keyReturn = substr(microtime(true),2,8).rand(0,99);
$resReturn= [
'action' =>'return',
'position'=>[
'x'=>4085,
'y'=>377
],
];
$array["F".$keyReturn] = $resReturn;
break;
}
return [$array,$keyReturn,$resReturn];
}
//多伦会话匹配关键词结果数组
public function getMulResultSynonym($speechId)
{
$resultSynonym = [];
$synonymList = SpeechMulLabelSynonym::create()->getAll(["speech_id"=>$speechId]);
foreach ($synonymList as $val){
if(isset($val["sls_name"])) {
$resultSynonym[$val["node_mul_id"]][$val["sls_keyword"]][] = $val["sls_name"];
}
}
return $resultSynonym;
}
//获取所有子节点
public function getMulProcessNodesNode($flow,$nodesMul,$resultMulSynonym,$childMulParent,$nodesMulInfo,$targetMulLabel,$nodeSynonymList,$treeFirstNode)
{
//判断是否有相同的节点
$sameNodeList = [];
$processMulNodesNode = [];
$processMulNodesArr = [];//所有全局话术的根节点
//用一个权重数组去获取最终值吧(始终取最大的)
$priorityArray = [];
foreach ($nodesMul as $key=>$value)
{
$valueProcessId = $value["process_mul_id"];
$processMulNodesArr[$valueProcessId][] = $value;
$subFlowModel = [];
$valueNodesId = $value["nodes_id"];
$valueParentId = $value["parent_id"];
$valueNodeId = "F".$value["node_mul_id"]."_".$value["node_mul_id"];
$priority = "0";
if($valueNodesId) {
$word = $targetMulLabel[$valueNodesId]??"";
if ($word) {
$synonymCode = "W." . $word;
$yesSynonym = [];
$isMore = 0;
$arrSubFlow = [];
$synonymArray = [];
switch ($word){
case "肯定":
if(isset($resultMulSynonym[$childMulParent[$valueNodesId]]["yes"])) {
$yesSynonym = array_values($resultMulSynonym[$childMulParent[$valueNodesId]]["yes"]);
}
$priority = "5";
break;
case "否定":
if(isset($resultMulSynonym[$childMulParent[$valueNodesId]]["no"])) {
$yesSynonym = array_values($resultMulSynonym[$childMulParent[$valueNodesId]]["no"]);
}
$priority = "10";
break;
case "拒绝":
if(isset($resultMulSynonym[$childMulParent[$valueNodesId]]["reject"])) {
$yesSynonym = array_values($resultMulSynonym[$childMulParent[$valueNodesId]]["reject"]);
}
$priority = "12";
break;
case "默认":
$priority = "2";
$isMore = 1;
break;
}
if($isMore==0) {//不是默认
$synonymSystem = $yesSynonym ?: [$synonymCode];
foreach ($synonymSystem as $item){
$synonymArray[$item] = $word;
}
$arrSubFlow = [
"condition" => [
"text" => $synonymSystem
],
"priority" => $priority,
"description" => $word
];
}elseif($isMore==1){//是默认
$arrSubFlow = [
"condition" => [
"text" => ["any"]
],
"priority" => $priority,
"description" => $word
];
}
if(!isset($priorityArray[$valueNodeId])) {
$priorityArray[$valueNodeId] = $priority;
}else{
if($priorityArray[$valueNodeId]<$priority){
$priorityArray[$valueNodeId] = $priority;
}
}
if($nodesMulInfo[$value["node_mul_id"]]["info_talk_info"]) { //有信息的(多伦会话只要有信息判断)
if(!isset($sameNodeList[$valueProcessId][$valueParentId][$valueNodeId])) {//是否存在当前流程,当前父id的,节点id
//判断是否当前节点参数是否为空
$subFlowModel[$valueNodeId] = $arrSubFlow;
if($isMore==0) {//不是默认
$nodeSynonymList[$valueNodeId] = $synonymArray;
}
$sameNodeList[$valueProcessId][$valueParentId][$valueNodeId] = $key+1;
}else{
if(!isset($processMulNodesNode[$valueProcessId][$valueParentId][$valueNodeId]["condition"]["text"])) {
$processMulNodesNode[$valueProcessId][$valueParentId][$valueNodeId]["condition"]["text"] = [];
}
if($isMore==0) {//非默认
if ($yesSynonym) {
$processMulNodesNode[$valueProcessId][$valueParentId][$valueNodeId]["condition"]["text"] = array_merge($processMulNodesNode[$valueProcessId][$valueParentId][$valueNodeId]["condition"]["text"] ,$yesSynonym);
}
if (!$yesSynonym) {
array_push($processMulNodesNode[$valueProcessId][$valueParentId][$valueNodeId]["condition"]["text"], "W." . $word);
}
$nodeSynonymList[$valueNodeId] = array_merge($nodeSynonymList[$valueNodeId],$synonymArray);
}
if($isMore==1) {//默认
// $processMulNodesNode[$valueProcessId][$valueParentId][$valueNodeId]["condition"]["text"]= ["any"];
array_push($processMulNodesNode[$valueProcessId][$valueParentId][$valueNodeId]["condition"]["text"], "any");
}
if(!isset($processMulNodesNode[$valueProcessId][$valueParentId][$valueNodeId]["description"])) {
$processMulNodesNode[$valueProcessId][$valueParentId][$valueNodeId]["description"] = $word;
}else{
$processMulNodesNode[$valueProcessId][$valueParentId][$valueNodeId]["description"] .= "," . $word;
}
$processMulNodesNode[$valueProcessId][$valueParentId][$valueNodeId]["priority"] = $priorityArray[$valueNodeId];
}
}
elseif(!$nodesMulInfo[$value["node_mul_id"]]["info_talk_info"] && $nodesMulInfo[$value["node_mul_id"]]["type_id"]==2){
$next = $nodesMulInfo[$value["node_mul_id"]]["next"]; //跳转的条件
$nextId = $nodesMulInfo[$value["node_mul_id"]]["next_id"];//流程id
[$arrSubFlows,$returnKey,$resReturn,$flow] = $this->checkNextMulFlow($next,$nextId,$treeFirstNode,$flow);
if(!isset($sameNodeList[$valueProcessId][$valueParentId][$returnKey])) {
//判断是否当前节点参数是否为空
if($resReturn){
if(!isset($subFlowModel["F" . $returnKey]["condition"]["text"])) {
$subFlowModel["F" . $returnKey]["condition"]["text"] = [];
}
if($isMore==0) {//非默认
if ($yesSynonym) {
$subFlowModel["F" . $returnKey]["condition"]["text"] = array_merge($processMulNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"],$yesSynonym);
}
if (!$yesSynonym ) {
array_push($subFlowModel ["F" . $returnKey]["condition"]["text"], "W." . $word);
}
}
if($isMore==1) {//默认
// $subFlowModel ["F" . $returnKey]["condition"]["text"]= ["any"];
array_push($subFlowModel ["F" . $returnKey]["condition"]["text"], "any");
}
$subFlowModel["F" . $returnKey]["priority"] = $priorityArray[$valueNodeId];
}
if($isMore==0) {//不是默认
$nodeSynonymList[$valueNodeId] = $synonymArray;
}
// $subFlowModel["F".$returnKey] = $resReturn;
$sameNodeList[$valueProcessId][$valueParentId][$returnKey] = $key+1;
}else{
if(!isset($processMulNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"])) {
$processMulNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"] = [];
}
if($isMore==0) {//非默认
if ($yesSynonym) {
$processMulNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"] = array_merge($processMulNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"],$yesSynonym);
}
if (!$yesSynonym ) {
array_push($processMulNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"], "W." . $word);
}
$nodeSynonymList[$valueNodeId] = array_merge($nodeSynonymList[$valueNodeId],$synonymArray);
}
if($isMore==1) {//默认
// $processMulNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"]= ["any"];
array_push($processMulNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["condition"]["text"], "any");
}
if(!isset($processMulNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["description"])){
$processMulNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["description"] = ",".$word;
}else{
$processMulNodesNode[$valueProcessId][$valueParentId] ["F" . $returnKey]["description"] .= ",".$word;
}
$processMulNodesNode[$valueProcessId][$valueParentId]["F" . $returnKey]["priority"] = $priorityArray[$valueNodeId];
}
}
}
}
if (!isset($processMulNodesNode[$valueProcessId][$valueParentId])) {
$processMulNodesNode[$valueProcessId][$valueParentId] = $subFlowModel;
} else {
$processMulNodesNode[$valueProcessId][$valueParentId] = array_merge($processMulNodesNode[$valueProcessId][$valueParentId],$subFlowModel);
}
}
return [$processMulNodesNode,$nodeSynonymList,$processMulNodesArr,$flow];
}
//获取所有的
public function getMulFlowList($flow,$processMulNodesArr,$argMulArray,$nodesMulInfo,$treeFirstNode,$processMulNodesNode,$allNodeMulWavKey,$priority)
{
$count = 0;
foreach ($processMulNodesArr as $ke=>$ve){
foreach ($ve as $kkk=>$vvv){
$vvvNodeId = $vvv["node_mul_id"];
$count++;
$arg = [];
$arg["action"] = "cti_play_and_detect_speech";
//模式
$argM = $argMulArray[$vvvNodeId]["moshi"]??"1";
$argLuZao = $argMulArray[$vvvNodeId]["luzao"]??"";
$argKaiShi = $argMulArray[$vvvNodeId]["kaishi"]??"";
$argTingZhi = $argMulArray[$vvvNodeId]["tingzhi"]??"";
$argDengDai = $argMulArray[$vvvNodeId]["dengdai"]??"";
$argZuiDa = $argMulArray[$vvvNodeId]["zuida"]??"";
$argCanShu = $argMulArray[$vvvNodeId]["canshu"]??"";
$argLuYin = $argMulArray[$vvvNodeId]["luyin"]??"";
//挂机不需要这些参数
if($nodesMulInfo[$vvvNodeId]['next']!=1) {
$arg["filter"] = [
"text" => "S",
"dtmf" => "none"
];
if ($priority == 1) {
$arg["kb_priority"] = 0;
} elseif ($priority == 2) {
$arg["kb_priority"] = 1;
}
$arg["timeoutplaybacks"] = [];
$arg["timeoutrepetition"] = "";
$arg["mismatchplaybacks"] = [];
$arg["mismatchrepetition"] = "1";
$arg["kb"] = 'C1';
$arg["globalflow"] = [
"all"
];
}else{//挂机节点不起用asr
$argM = 0;
}
$arg["argument"] = "'$argM' '16' '' '$argLuZao' '' '$argKaiShi' '$argTingZhi' '$argDengDai' '$argZuiDa' '' '$argCanShu' '$argLuYin' '' ''";
$arg["position"] = [
"x"=>$nodesMulInfo[$vvvNodeId]["node_x"],
"y"=>$nodesMulInfo[$vvvNodeId]["node_y"]];
$arg["description"] = $nodesMulInfo[$vvvNodeId]["info_title"];
if(isset($allNodeMulWavKey[$vvvNodeId]) && $allNodeMulWavKey[$vvvNodeId]) {
$arg["playbacks"] = [$allNodeMulWavKey[$vvvNodeId]];
}else{
$arg["playbacks"] = [$nodesMulInfo[$vvvNodeId]["info_talk_info"]];
}
if(isset($processMulNodesNode[$vvv["process_mul_id"]][$vvvNodeId])) {
$arg["subflow"] = $processMulNodesNode[$vvv["process_mul_id"]][$vvvNodeId];
}else{
$next = $nodesMulInfo[$vvvNodeId]["next"]; //跳转的条件
$nextId = $nodesMulInfo[$vvvNodeId]["next_id"];//流程id
[$arg["subflow"],$returnKey,$resReturn,$flow] = $this->checkNextMulFlow($next,$nextId,$treeFirstNode,$flow);
}
if($nodesMulInfo[$vvvNodeId]["info_talk_info"]) {//如果是跳转节点,没有输入声音就是不输入
$keyNode = "F".$vvvNodeId."_".$vvvNodeId;
$flow[$keyNode] = $arg;
}
}
}
return $flow;
}
//多伦会话下一步
public function checkNextMulFlow($next,$nextId,$treeFirstNode,$flow)
{
$array = [];
$info = ["description"=>"默认回答", "condition"=>["text"=>["any"]]];
$keyReturn = "";
$resReturn = "";
switch ($next)
{
case 0://普通节点默认挂机
case 1://挂机
$hangK = substr(microtime(true),2,8).rand(0,99);
$hangKey = "F".$hangK;
$array[$hangKey] = $info;
$keyReturn = $hangK;
$resReturn = $info;
//挂机节点需要添加挂机节点
/**
* 生成一个挂机节点
*/
$endPointsArray = [
'action'=>'hangup',
'position'=>[
"x"=>67,
"y"=>33
]
];
$flow[$hangKey]=$endPointsArray;
break;
case 2://跳转指定多伦会话
$hangKey = "F".$nextId."_".$nextId;
$array[$hangKey] = $info;
$keyReturn = $nextId."_".$nextId;
$resReturn = $info;
break;
case 3://指定主流程
$hangKey = "F".$treeFirstNode[$nextId]['node_id'];
$array[$hangKey] = $info;
$keyReturn = $treeFirstNode[$nextId]['node_id'];
$resReturn = $info;
break;
}
return [$array,$keyReturn,$resReturn,$flow];
}
//所有的多伦会话节点流程
public function getMulArgArray($where)
{
$argList = SpeechMulProcessSettingModel::create()->getAll($where,"set_key,set_value,node_mul_id");//所有的参数节点流程
$argArray = [];
foreach ($argList as $argK=>$argValue){
$argArray[$argValue["node_mul_id"]][$argValue["set_key"]] = $argValue["set_value"];
}
return $argArray;
}
}