#include "StdAfx.h" #include "TaskMgr.h" #include "TaskInc.h" #include "CtiCore.h" #include "MsgCenter.h" #include "LineHolder.h" #include "LogicLine.h" SINGLETON_IMPLEMENT(CTaskMgr) CTaskMgr::CTaskMgr(void) { } CTaskMgr::~CTaskMgr(void) { } /***************************************************************** **【函数名称】 __addTask **【函数功能】 添加Task **【参数】 **【返回值】 ****************************************************************/ void CTaskMgr::__addTask( CTask* pTask ) { m_TaskLock.Lock(); m_TaskTable.SetAt(reinterpret_cast(pTask), pTask); m_TaskLock.Unlock(); } /***************************************************************** **【函数名称】 __onAgentLogin **【函数功能】 坐席签入处理 **【参数】 消息实体 **【返回值】 ****************************************************************/ void CTaskMgr::__onAgentLogin( CPduEntity &PduEntity ) { // 显示日志 ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("Agent->CTI, CMD = [坐席签入], \ Exten = %d, Agent = %d"), PduEntity.GetDataUInt(1), PduEntity.GetDataUInt(2)); // 设置内线分机的当前坐席工号 CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(PduEntity.GetDataUInt(1)); if(pLine == NULL) ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING, _T("{TaskMgr}: 坐席[%d]签入绑定分机失败: 无法获取目标分机[%d]"), PduEntity.GetDataUInt(2), PduEntity.GetDataUInt(1)); else pLine->setAgentNum(PduEntity.GetDataUInt(2)); } /***************************************************************** **【函数名称】 __onAgentLogout **【函数功能】 坐席签出处理 **【参数】 消息实体 **【返回值】 ****************************************************************/ void CTaskMgr::__onAgentLogout( CPduEntity &PduEntity ) { // 显示日志 ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("Agent->CTI, CMD = [坐席签出], Exten = %d, Agent = %d"), PduEntity.GetDataUInt(1), PduEntity.GetDataUInt(2)); // 设置内线分机的当前坐席工号 CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(PduEntity.GetDataUInt(1)); if(pLine != NULL) pLine->setAgentNum(0); } /***************************************************************** **【函数名称】 __onAgentReset **【函数功能】 重置处理 **【参数】 消息实体 **【返回值】 ****************************************************************/ void CTaskMgr::__onAgentReset( CPduEntity &PduEntity ) { // 显示日志 ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("Agent->CTI, CMD = [坐席重置], Exten = %d"), PduEntity.GetDataUInt(1)); // 获取线路类指针 CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(PduEntity.GetDataUInt(1)); if(pLine == NULL) return; // 删除关联任务 removeTask(pLine->taskIdBinded()); // 物理重置 CCtiCore::GetInstance().getDevLink().exec(-1, LINE_OP_RESET, pLine->lineId(), NULL); } /***************************************************************** **【函数名称】 __onTaskFailed **【函数功能】 处理Task执行失败 **【参数】 消息实体 **【返回值】 ****************************************************************/ void CTaskMgr::__onTaskFailed( CTask* pTask, CPduEntity &PduEntity ) { // 显示日志 CString DevType; UINT HostLine; if(PduEntity.GetLocalDevType() == PDU_DEV_TYPE_ACD) { DevType = _T("ACD"); HostLine = PduEntity.GetDataUInt(1); } else { DevType = _T("IVR"); HostLine = PduEntity.GetDataUInt(3); } ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING, _T("CTI->%s, CMD[%d]执行失败, Line = %d"), DevType, PduEntity.GetCmdType(), HostLine); // 命令返回 PduEntity.SetToExecReturn(); PduEntity.SetDataBool(0, false); CInterfaceWindow::getIocpCommInstance()->Send(&PduEntity, PduEntity.GetLocalDevType(), PduEntity.GetLocalDevId()); // 移除Task removeTask(reinterpret_cast(pTask)); } /***************************************************************** **【函数名称】 __procDevOpProcess **【函数功能】 处理设备操作进展 **【参数】 EvtType 消息事件类型 lpContent 消息内容 **【返回值】 ****************************************************************/ void CTaskMgr::__procDevOpProcess( UINT EvtType, const PARAM lpContent ) { EventOpProcess &EvtInfo = *(EventOpProcess*)lpContent; // 查找到Task并处理 CTask* pTask = findTask(EvtInfo.nInstance); if(pTask != NULL) pTask->OnDevOpProcess(EvtInfo); } /***************************************************************** **【函数名称】 __procDevOpResult **【函数功能】 设备操作结果返回 **【参数】 EvtType 消息事件类型 lpContent 消息内容 **【返回值】 ****************************************************************/ void CTaskMgr::__procDevOpResult( UINT EvtType, const PARAM lpContent ) { EventOpResult &EvtInfo = *(EventOpResult*)lpContent; // 查找到Task并处理 CTask* pTask = findTask(EvtInfo.nInstance); if(pTask != NULL) { // 返回True代表处理完成,移除Task if(pTask->OnDevOpResult(EvtInfo)) removeTask(EvtInfo.nInstance); } } /***************************************************************** **【函数名称】 __procDevOperator **【函数功能】 设备主动操作 **【参数】 EvtType 消息事件类型 lpContent 消息内容 **【返回值】 ****************************************************************/ void CTaskMgr::__procDevOperator( UINT EvtType, const PARAM lpContent ) { CTask *pTask = NULL; // 事件内容解析 EventDevOperation &EvtInfo = *(EventDevOperation*)lpContent; switch(EvtInfo.nOpType) { case DEV_OP_CALL_IN: // 外线来电 pTask = new CTaskDevCallIn(EvtInfo); break; case DEV_OP_CALL_OUT: // 物理外呼 pTask = new CTaskDevCall(EvtInfo); break; default: break; } if(pTask == NULL) return; // 保存Task __addTask(pTask); // 返回Fals代表执行失败,移除Task if(!pTask->DoTask()) removeTask((long)pTask); } /***************************************************************** **【函数名称】 init **【函数功能】 模块初始化 **【参数】 **【返回值】 ****************************************************************/ void CTaskMgr::init( void ) { // 注册底层设备消息和设备操作结果 CMsgCenter& MC = CMsgCenter::GetInstance(); MC.regist(DEV_EVENT_DEV_OPERATOR, this); MC.regist(DEV_EVENT_LINE_OP_PROCESS, this); MC.regist(DEV_EVENT_LINE_OP_RESULT, this); } /***************************************************************** **【函数名称】 removeTask **【函数功能】 删除Task **【参数】 **【返回值】 ****************************************************************/ void CTaskMgr::removeTask( long TaskId ) { if(TaskId == TASK_ID_INVALID) return; m_TaskLock.Lock(); CTask* pTask = NULL; if(m_TaskTable.Lookup(TaskId, pTask)) { m_TaskTable.RemoveKey(TaskId); // 删除Task ASSERT(pTask != NULL); delete pTask; } m_TaskLock.Unlock(); } /***************************************************************** **【函数名称】 findTask **【函数功能】 查找Task **【参数】 **【返回值】 ****************************************************************/ CTask* CTaskMgr::findTask( long TaskId ) { if(TaskId == TASK_ID_INVALID) return NULL; CTask* pTask = NULL; m_TaskLock.Lock(); m_TaskTable.Lookup(TaskId, pTask); m_TaskLock.Unlock(); return pTask; } /***************************************************************** **【函数名称】 onPduMessage **【函数功能】 Pdu命令处理接口 **【参数】 PduEntity: 消息实体 **【返回值】 ***************************************************************/ void CTaskMgr::onPduMessage( CPduEntity &PduEntity ) { // 根据命令类型创建Task CTask *pTask = NULL; PDU_CMD_TYPE nCmdType = PduEntity.GetCmdType(); switch(nCmdType) { case PDU_CMD_AGENT_LOGIN: // 坐席签入 __onAgentLogin(PduEntity); break; case PDU_CMD_AGENT_LOGOUT: // 坐席签出 __onAgentLogout(PduEntity); break; case PDU_CMD_AGENT_MAKECALL: // 坐席外呼 pTask = new CTaskAgentCall(PduEntity); break; case PDU_CMD_AGENT_ANSWER: // 坐席应答 pTask = new CTaskAgentAnswer(PduEntity); break; case PDU_CMD_AGENT_HANGUP: // 坐席挂机 pTask = new CTaskAgentHungUp(PduEntity); break; case PDU_CMD_AGENT_CANCEL: // 坐席取消操作 pTask = new CTaskAgentCancel(PduEntity); break; case PDU_CMD_AGENT_RESET: // 坐席重置 __onAgentReset(PduEntity); break; case PDU_CMD_AGENT_HOLD: // 坐席保持 pTask = new CTaskAgentHold(PduEntity); break; case PDU_CMD_AGENT_TAKEBACK: // 坐席接回 pTask = new CTaskAgentTakeBack(PduEntity); break; case PDU_CMD_AGENT_TRANSTALK: // 坐席转移 pTask = new CTaskAgentTransfer(PduEntity); break; case PDU_CMD_AGENT_THREETALK: // 坐席三方 pTask = new CTaskAgentThreeTalk(PduEntity); break; case PDU_CMD_AGENT_CONSULTATION_CALL:// 协商呼叫 pTask = new CTaskAgentConsulCall(PduEntity); break; case PDU_CMD_AGENT_CONFIRM_TRANSFER:// 确认转移 onTaskPduMsg(PduEntity.GetDataUInt(1), PduEntity); break; case PDU_CMD_AGENT_MONI_LISTEN: // 监听 pTask = new CTaskMonitorListen(PduEntity); break; case PDU_CMD_AGENT_MONI_REPLACE: // 代接 pTask = new CTaskMonitorInstead(PduEntity); break; case PDU_CMD_AGENT_MONI_INSERT: // 强插 pTask = new CTaskMonitorInsert(PduEntity); break; case PDU_CMD_AGENT_MONI_INTERCEPT: // 强截 pTask = new CTaskMonitorGrab(PduEntity); break; case PDU_CMD_AGENT_MONI_CUT: // 强拆 pTask = new CTaskMonitorCut(PduEntity); break; case PDU_CMD_AGENT_FAX: // 坐席传真 pTask = new CTaskAgentFax(PduEntity); break; case PDU_CMD_AGENT_TURN_TO_IVR: // 坐席转IVR pTask = new CTaskAgentTurnIvr(PduEntity); break; case PDU_CMD_AGENT_MUTE: // 坐席静音 pTask = new CTaskAgentMute(PduEntity); break; case PDU_CMD_IVR_HANGUP: // Ivr通知挂机 pTask = new CTaskIvrHangUp(PduEntity); break; case PDU_CMD_IVR_TURN_AGENT: // IVR通知转坐席 pTask = new CTaskIvrTurnAgent(PduEntity); break; case PDU_CMD_IVR_QUEUE_CONTINUE: // Ivr通知继续排队 pTask = new CTaskIvrContinueQuene(PduEntity); break; case PDU_CMD_IVR_PLAY_DTMF: // IVR通知放音收按键 pTask = new CTaskIvrPlayVoice(PduEntity); break; case PDU_CMD_IVR_CALL_OUT: // IVR呼叫 pTask = new CTaskIvrCall(PduEntity); break; case PDU_CMD_IVR_TURN_OUTLINE: // IVR呼叫转移外线 pTask = new CTaskIvrTurnOut(PduEntity); break; case PDU_CMD_IVR_FAX: // Ivr收发传真 pTask = new CTaskIvrFax(PduEntity); break; case PDU_CMD_IVR_LEAVE_WORD: // Ivr留言 pTask = new CTaskIvrLeaveWord(PduEntity); break; default: break; } if(pTask == NULL) return; // 保存Task __addTask(pTask); // 返回Fase代表操作失败,移除该Task if(!pTask->DoTask()) __onTaskFailed(pTask, PduEntity); } /***************************************************************** **【函数名称】 onTaskPduMsg **【函数功能】 Task处理Pdu命令接口 **【参数】 LineId: 线路ID PduEntity:消息实体 **【返回值】 ***************************************************************/ void CTaskMgr::onTaskPduMsg( UINT LineId, CPduEntity &PduEntity ) { CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(LineId); ASSERT(pLine != NULL); if(pLine == NULL) { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{TaskMgr}: Task处理PDU命令失败, 无法定位关联线路[%d]"), LineId); return; } CTask* pTask = findTask(pLine->taskIdBinded()); if(pTask == NULL) { pLine->taskIdBinded() = TASK_ID_INVALID; if(PduEntity.GetCmdType() == PDU_CMD_AGENT_CONFIRM_TRANSFER) { // 返回命令 PduEntity.SetToExecReturn(); PduEntity.SetDataBool(0, false); CInterfaceWindow::getIocpCommInstance()->Send(&PduEntity, PduEntity.GetLocalDevType(), PduEntity.GetLocalDevId()); } } else { // task处理Pdu命令返回成功,删除task if(pTask->OnCmdOperation(PduEntity)) removeTask((long)pTask); } } /***************************************************************** **【函数名称】 onMessage **【函数功能】 消息事件处理函数 **【参数】 EvtType 消息事件类型 lpContent 消息内容 **【返回值】 ****************************************************************/ void CTaskMgr::onMessage( UINT MsgType, const PARAM lpContent ) { if(lpContent == NULL) return; switch(MsgType) { case DEV_EVENT_LINE_OP_PROCESS: // 设备操作进展 __procDevOpProcess(MsgType, lpContent); break; case DEV_EVENT_LINE_OP_RESULT: // 设备操作结果 __procDevOpResult(MsgType, lpContent); break; case DEV_EVENT_DEV_OPERATOR: // 设备主动操作 __procDevOperator(MsgType, lpContent); break; } }