当前位置: 首页 > news >正文

新一代电话机器人开源PHP源代码

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

相关文章:

新一代电话机器人开源PHP源代码

使用easyswoole 框架开发的 新一代电话机器人开源PHP源码 项目地址&#xff1a;https://gitee.com/ddrjcode/robotphp 代理商页面演示地址 http://119.23.229.15:8080 用户名&#xff1a;c0508 密码&#xff1a;123456 包含 AI外呼管理&#xff0c;话术管理&#xff0c;CR…...

dockerdocker-copose_限制容器cpu和内存

本文目录 docker的限制方式限制CPU占用限制内存占用 docker-compose docker的限制方式 限制CPU占用 Docker使用--cpus参数来限制容器的CPU资源。该参数指定了分配给容器的CPU核心数量或百分比。 例子&#xff1a;限制CPU使用个数 docker run --cpus2 <imageName>以上…...

【leetcode】圆圈中最后剩下的数字

目录 1. 问题 2. 思路 3. 代码 4. 运行 1. 问题 本题即为典型的约瑟夫问题&#xff0c;通过递推公式倒推出问题的解。原始问题是从n个人中每隔m个数踢出一个人&#xff0c;原始问题变成从n-1个人中每隔m个数踢出一个人…… 示例 1&#xff1a; 输入: n 5, m 3 输出: 3…...

利用python批量将.shp文件转换坐标生成.geojson文件,再将.geojson转换成.csv文件,最后将csv文件插入数据库表

第一步&#xff1a;.shp批量转.geojson # author: JMY # 创建时间: 2024/2/26 17:12 # 批量将.shp文件生成geojson文件并转换坐标为3857import os import geopandas as gpd# 定义输入和输出文件夹路径 input_folder shp文件 output_folder geojson文件# 定义输入和输出坐标系…...

远程服务器Ubuntu 18.04安装VNC远程桌面

一、安装vnc 1.安装图形化界面工具 # 安装过程中会弹窗让选择配置&#xff0c;选lightdm sudo apt install ubuntu-desktop sudo apt-get install gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal 2.安装vnc sudo apt-get install x11vnc3.安装LightD…...

30天自制操作系统(第23天)

23.1 编写malloc 参考第22天的内容&#xff0c;在绘制窗口前先分配了150*50个字节大小的内存&#xff0c;所以导致该文件经编译后有7.6k左右&#xff0c;能否在其中使用指针呢&#xff1f;当需要开辟空间时&#xff0c;移动指针即可。在之前的章节中也有函数memman_alloc函数可…...

基于Rust语言,和WebAssembly技术,与JavaScript结合,的具体应用场景

基于Rust语言与WebAssembly&#xff08;Wasm&#xff09;技术并与JavaScript结合&#xff0c;可以应用于多个场景&#xff0c;特别是在需要高性能和/或低级系统访问的情况下。下面是一些具体的应用场景&#xff1a; 性能密集型任务: Rust加上Wasm适合执行计算密集型任务&#x…...

【MATLAB源码-第154期】基于matlab的OFDM系统多径信道下块状和梳妆两种导频插入方式误码率对比仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 OFDM&#xff08;Orthogonal Frequency Division Multiplexing&#xff0c;正交频分复用&#xff09;是一种高效的无线信号传输技术&#xff0c;广泛应用于现代通信系统&#xff0c;如Wi-Fi、LTE和5G。OFDM通过将宽带信道划分…...

Linux 下 socket 编程介绍及 TCP 客户端与服务端创建示例

目录 socket 编程接口TCP 服务端TCP 客户端更多内容 本文介绍了 Linux 下的 socket 编程&#xff0c;及总结了使用 socket 接口实现 TCP 服务端和客户端的示例代码。 socket 编程接口 socket() 函数&#xff1a;用于创建一个新的 socket 描述符&#xff1a; int socket(int …...

JetBrains Gateway Github Copilot 客户端插件和主机插件

JetBrains Gateway可以通过插件支持Github Copilot&#xff08;需另行注册&#xff09;。 需要安装插件 客户端&#xff0c;而非插件 主机&#xff0c;如图所示&#xff1a; 大概是因为代码显示在客户端&#xff08;运行在本地的IDE&#xff09;&#xff1f;...

【web APIs】3、(学习笔记)有案例!

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、概念其他事件页面加载事件元素滚动事件页面尺寸事件 元素尺寸与位置 二、案例举例电梯导航 前言 掌握阻止事件冒泡的方法理解事件委托的实现原理 一、概念…...

使用css reset 还是使用Normalize.css

文章目录 使用css reset 还是使用Normalize.cssCSS Reset:Normalize.css:总结Normalize.css 的使用&#xff08;例如Vue 3.0 和 Vue CLI 4.x 项目&#xff09;1.安装2.main.js 中导入3.测试引用是否成功。 使用css reset 还是使用Normalize.css 使用 CSS Reset 还是 Normalize…...

英语中的提问方式(问法)(bug提问、bug描述)

文章目录 英语提问方式一、单词、短语、句子的意思1.1 提问单词的意思1.2 提问短语的意思1.3 提问句子的意思 二、在编程中提问2.1 提问bug2.2 请求代码帮助 如何提出反问句1. 构建反问句的基本结构2. 提问反问句的方法3. 理解反问句的意图 在口语中提问&#xff1a;确保清晰度…...

xss.haozi.me靶机练习

目录 第零关&#xff1a; 第一关&#xff1a; 第二关&#xff1a; 第三关&#xff1a; 第四关&#xff1a; 第五关&#xff1a; 第六关&#xff1a; 第七关&#xff1a; 第八关&#xff1a; 第九关&#xff1a; 第十关&#xff1a; 第十一关&#xff1a; 第十二关…...

2.1 mov、add和sub加减指令实操体验

汇编语言 1. mov操作 1.1 mov移动值 mov指令把右边的值移动到左边 mount c d:masm c: debug r ax 0034 r 073f:0100 mov ax,7t1.2 mov移动寄存器的值 把右边寄存器的值赋值给左边的寄存器 a 073f:0105 mov bx,axt1.3 mov高八位&#xff08;high&#xff09;和低八位&am…...

计算机设计大赛 深度学习机器视觉车道线识别与检测 -自动驾驶

文章目录 1 前言2 先上成果3 车道线4 问题抽象(建立模型)5 帧掩码(Frame Mask)6 车道检测的图像预处理7 图像阈值化8 霍夫线变换9 实现车道检测9.1 帧掩码创建9.2 图像预处理9.2.1 图像阈值化9.2.2 霍夫线变换 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分…...

中间件安全(概述)有中间件的各类链接和官网信息和漏洞库以及配置问题和开源工具

分类主要包括Apache、IIS、Tomcat、weblogic、websphere、Jboss等相关的技术知识和实践。 以Apache为例讲一讲如何保证中间件安全 中间件安全是指保护中间件软件和服务的安全性&#xff0c;防止被恶意攻击或者滥用。中间件软件是指在操作系统和应用程序之间提供通信和集成功能…...

Unity铰链四杆机构设计和运动仿真

一、效果图 设定好各边长度和转速后&#xff0c;点击【设置并启动】&#xff0c;自动生成一个机构模型&#xff0c;并按照原理进行运转 二、铰链四杆机构介绍 机架&#xff1a;A和D是固定位置&#xff0c;叫做机架。 曲柄&#xff1a;B点绕A点旋转&#xff0c;构成曲柄。 连…...

Python爬虫——解析常用三大方式之Xpath

目录 Xpath 安装xpath 安装lxml库 导入lxml库 解析本地文件 etree.parse&#xff08;&#xff09; 解析服务器响应文件 etree.HTML() xpath基本语法 小案例&#xff1a;获取百度首页的百度一下 大案例&#xff1a;爬取站长素材图片 总结 Xpath 安装xpath 首先要学会安…...

C#判断DataTable1 A列的集合是否为DataTable2 B列的集合的子集

DataSet ds2 (DataSet)res2.Anything; // 检查 集合B是否为集合A的子集 var table1MaterialCodes ds.Tables[2].AsEnumerable().Select(row > row["Code"]).ToList(); //DataSet1 表Code列集合A var table2MaterialCodes ds2.Tables[0].AsEnumerable().Selec…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...