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

开源 0

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

也许您对下面的内容还感兴趣: