#include "StdAfx.h" #include "IvrFlow.h" #include "LineHolder.h" #include "LogicLine.h" #include "NetworkCti.h" #include "TaskMgr.h" #include "StatisticsMgr.h" CIvrFlow::CIvrFlow(int FlowId) : m_IvrFlowId(FlowId), m_LineId(-1), m_IsQuene(false) { } CIvrFlow::~CIvrFlow(void) { } /***************************************************************** **【函数名称】 EndIvr **【函数功能】 IVR流程结束 **【参数】 **【返回值】 ****************************************************************/ void CIvrFlow::resetFlow() { m_IsQuene = false; m_LineId = -1; } /***************************************************************** **【函数名称】 ProcLineHangUp **【函数功能】 处理线路挂机 **【参数】 **【返回值】 ****************************************************************/ void CIvrFlow::procLineHangUp() { // 获取线路类对象指针 CLogicLine *pLogicLine = CLineHolder::GetInstance().getLogicLine(m_LineId); if(pLogicLine == NULL) return; // 正在排队向ACD发送取消排队命令 // 排队标志清除 m_IsQuene = false; CPduEntity CmdCancelQuene(PDU_CMD_IVR_QUEUE_CANCEL); CmdCancelQuene.SetDataInt(1, m_IvrFlowId); CmdCancelQuene.SetDataULong(2, pLogicLine->callId()); CNetworkCti::GetInstance().send2ACD(CmdCancelQuene); // 向IVR发送挂机命令 CPduEntity CmdHangUp(PDU_CMD_CTI_IVR_HANGUP); CmdHangUp.SetDataInt(1, m_IvrFlowId); CmdHangUp.SetDataULong(2, pLogicLine->callId()); CNetworkCti::GetInstance().send2IVR(CmdHangUp); // 流程重置 resetFlow(); } /***************************************************************** **【函数名称】 OnPduMessage **【函数功能】 Pdu命令处理接口 **【参数】 PduEntity: 消息实体 **【返回值】 ***************************************************************/ void CIvrFlow::onPduMessage(CPduEntity &PduEntity) { switch(PduEntity.GetCmdType()) { case PDU_CMD_IVR_END: // 流程结束 this->resetFlow(); break; case PDU_CMD_CTI_IVR_CALLIN: // CallIn返回命令 __procCallInReturn(PduEntity); break; case PDU_CMD_CTI_IVR_TURNIVR: // 转Ivr命令返回 __procTurnIvrReturn(PduEntity); break; case PDU_CMD_IVR_WANT_AGENT: // 请求排队命令 __procWantAgent(PduEntity); break; case PDU_CMD_IVR_QUEUE_CONTINUE: // 继续排队命令 __procContinueQuene(PduEntity); break; case PDU_CMD_IVR_QUEUE_CANCEL: // 取消排队命令 __procCancelQuene(PduEntity); break; case PDU_CMD_IVR_HANGUP: // Ivr挂机 case PDU_CMD_IVR_TURN_AGENT: // 转人工 case PDU_CMD_IVR_PLAY_DTMF: // IVR通知放音收按键 case PDU_CMD_IVR_CALL_OUT: // IVR自动外呼 case PDU_CMD_IVR_TURN_OUTLINE: // IVR呼叫转移 case PDU_CMD_IVR_FAX: // IVR通知收发传真 case PDU_CMD_IVR_LEAVE_WORD: // IVR通知留言 __transmitToTask(PduEntity); break; } } /***************************************************************** **【函数名称】 __TransmitToTask **【函数功能】 转发命令给Task **【参数】 PduEntity: 消息实体 **【返回值】 ***************************************************************/ void CIvrFlow::__transmitToTask(CPduEntity &PduEntity) { // 设置IVR关联线路Id PduEntity.SetDataUInt(3, m_LineId == -1 ? 0 : m_LineId); if (PduEntity.GetCmdType() == PDU_CMD_IVR_TURN_AGENT) { PduEntity.SetDataUInt(3, m_LineId); PduEntity.SetDataUInt(4, 0); PduEntity.SetDataString(5, m_Callee); } //2019.3.7 __try { CTaskMgr::GetInstance().onPduMessage(PduEntity); } __except (EXCEPTION_EXECUTE_HANDLER) { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{CIvrFlow}:__transmitToTask,DoTask异常,CmdType=%d"), PduEntity.GetCmdType()); } } /***************************************************************** **【函数名称】 __ProcCallInReturn **【函数功能】 CallIn命令返回 **【参数】 PduEntity: 消息实体 **【返回值】 ***************************************************************/ void CIvrFlow::__procCallInReturn(CPduEntity &PduEntity) { // 关联线路 UINT LineId = PduEntity.GetDataUInt(5); CLogicLine *pLogicLine = CLineHolder::GetInstance().getLogicLine(LineId); if(pLogicLine == NULL) return; m_LineId = LineId; m_Caller = PduEntity.GetDataString(3); m_Callee = PduEntity.GetDataString(4); } /***************************************************************** **【函数名称】 __ProcTurnIvrReturn **【函数功能】 转IVR命令返回 **【参数】 PduEntity: 消息实体 **【返回值】 ***************************************************************/ void CIvrFlow::__procTurnIvrReturn(CPduEntity &PduEntity) { // 关联线路 m_LineId = PduEntity.GetDataUInt(5); // 转Ivr结果通知Task,由Task返回给Ivr程序 CTaskMgr::GetInstance().onTaskPduMsg(m_LineId, PduEntity); } /***************************************************************** **【函数名称】 __ProcWantAgentReturn **【函数功能】 请求排队命令 **【参数】 PduEntity: 消息实体 **【返回值】 ***************************************************************/ void CIvrFlow::__procWantAgent(CPduEntity &PduEntity) { if(PduEntity.GetIsExecReturn()) { // 显示日志 ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL,_T("ACD->CTI, CMD = return[来电排队], \ IVR = %d, IsSuccess = %u, Agent = %u, Ext = %u,Qcnt=%u"), PduEntity.GetDataInt(1), PduEntity.GetDataBool(0), PduEntity.GetDataUInt(9), PduEntity.GetDataUInt(10), PduEntity.GetDataUInt(11)); // 请求排队的返回命令 if(!PduEntity.GetDataBool(0)) { // 请求排队失败,向ACD发送暂停排队命令 CPduEntity CmdPauseQueue(PDU_CMD_CTI_ACD_QUEUE_PAUSE); CmdPauseQueue.SetDataInt(0, m_IvrFlowId); CNetworkCti::GetInstance().send2ACD(CmdPauseQueue); } else { // 排队成功设置排队标志为False m_IsQuene = false; } // 返回结果通知IVR CNetworkCti::GetInstance().send2IVR(PduEntity); } else { // 显示日志 ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("IVR->CTI, CMD = [来电排队], IVR = %d"), PduEntity.GetDataInt(1)); // 设置排队标志为TRUE m_IsQuene = true; // 转发给ACD请求排队 if(!CNetworkCti::GetInstance().send2ACD(PduEntity)) { // 发送失败通知IVR结果 PduEntity.SetToExecReturn(); PduEntity.SetDataBool(0, false); CNetworkCti::GetInstance().send2IVR(PduEntity); } // 统计 REP_EVENT_WANT_AGENT CLogicLine* pHostLine = CLineHolder::GetInstance().getLogicLine(m_LineId); if(pHostLine == NULL) return; CStatisticsMgr::GetInstance().onCallDetail(pHostLine->callId(), REP_EVENT_WANT_AGENT, m_LineId, NULL); } } /***************************************************************** **【函数名称】 __ProcContinueQuene **【函数功能】 继续排队命令 **【参数】 PduEntity: 消息实体 **【返回值】 ***************************************************************/ void CIvrFlow::__procContinueQuene(CPduEntity &PduEntity) { if(PduEntity.GetIsExecReturn()) { // 显示日志 ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL,_T("ACD->CTI, CMD = return[继续排队], \ IVR = %d, IsSuccess = %d, Agent = %d, Ext = %d"), PduEntity.GetDataInt(1), PduEntity.GetDataBool(0), PduEntity.GetDataUInt(7), PduEntity.GetDataUInt(8)); // ACD返回继续等待排队结果消息. 继续排队失败命令不处理 if(!PduEntity.GetDataBool(0)) return; // 排队成功修改排队标志 m_IsQuene = false; // 排队成功通知Task,由Task返回给Ivr程序 CTaskMgr::GetInstance().onTaskPduMsg(m_LineId, PduEntity); } else { // 通知Task等待排队 __transmitToTask(PduEntity); // 通知ACD继续排队 if(!CNetworkCti::GetInstance().send2ACD(PduEntity)) { // 发送失败通知IVR结果 PduEntity.SetToExecReturn(); PduEntity.SetDataBool(0, false); CNetworkCti::GetInstance().send2IVR(PduEntity); } } } /****************************************************************** **【函数名称】 __ProcCancelQuene **【函数功能】 取消排队 **【参数】 消息实体 **【返回值】 void ****************************************************************/ void CIvrFlow::__procCancelQuene(CPduEntity &PduEntity) { // 显示日志 ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("IVR->CTI, CMD = [取消排队], IVR = %d"), PduEntity.GetDataInt(1)); // 是否正在排队 if(!m_IsQuene) return; // 转发给ACD取消排队 CNetworkCti::GetInstance().send2ACD(PduEntity); // 设置排队标志为False m_IsQuene = false; }