| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- #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;
- }
|