使用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//$nodesInfopublic 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;}}