#include "StdAfx.h" #include "CellQueue.h" #include "NetworkIvr.h" #include "IvrFlow.h" #include "FlowDataProvider.h" IMPLEMENT_CELL_AUTOCREATE(CCellQueue, CELL_NAME_QUEUE) CCellQueue::CCellQueue(void) { m_AgentStrategy = AGENT_STRATEGY_KNOWN; // 坐席分配策略 m_GroupType = CELL_DATA_VAR; // 座席组类型,变量2、具体值1 m_VipLevelType = CELL_DATA_VAR; // vip客户级别值得类型,变量2、具体值1 m_SuccessPos = 0; // 成功分配坐席下一节点编号 m_NoFreePos = 0; // 没有空闲坐席下一节点编号 m_NoAgentPos = 0; // 没有坐席下一节点编号 m_HangUpPos = 0; // 挂机下一个处理节点 } CCellQueue::CCellQueue( CCellQueue & cellRequestAgent ) : CCellBase(cellRequestAgent) { m_GroupType = cellRequestAgent.m_GroupType; m_SpecifiedGroup = cellRequestAgent.m_SpecifiedGroup; m_AgentStrategy = cellRequestAgent.m_AgentStrategy; m_VipLevel = cellRequestAgent.m_VipLevel; m_VipLevelType = cellRequestAgent.m_VipLevelType; m_AgentVar = cellRequestAgent.m_AgentVar; m_ExtenVar = cellRequestAgent.m_ExtenVar; m_SuccessPos = cellRequestAgent.m_SuccessPos; m_NoFreePos = cellRequestAgent.m_NoFreePos; m_NoAgentPos = cellRequestAgent.m_NoAgentPos; m_HangUpPos = cellRequestAgent.m_HangUpPos; } CCellQueue::~CCellQueue(void) { } /***************************************************************** **【函数名称】 operate **【函数功能】 节点执行函数 **【参数】 **【返回值】 下一个节点编号 ****************************************************************/ int CCellQueue::operate( void ) { if(m_pIvrFlow == NULL) return CELL_OP_ERROR; CString Info; _getCellInfo(Info); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}: 开始执行[%s]"), Info); if(m_pIvrFlow->hangUpSign()) { m_pIvrFlow->hangUpSign() = false; ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}: 节点[%s]取消执行, 检测到外线挂机"), Info); return m_HangUpPos; } // 读取VIP级别 int nVipLevel = 1; if( m_VipLevelType == CELL_DATA_VAR ) // 变量模式 { CString strValue; if(m_pIvrFlow->findVarValue(m_VipLevel, strValue)) nVipLevel = atoi(strValue); } else // 具体值 { nVipLevel = atoi(m_VipLevel); } // 读取座席组 int nGroup = 0; if( m_GroupType == CELL_DATA_VAR ) // 变量模式 { CString strValue; if(m_pIvrFlow->findVarValue(m_SpecifiedGroup, strValue)) nGroup = atoi(strValue); } else // 具体值 { nGroup = atoi(m_SpecifiedGroup); } // 发送请求排队命令 CPduEntity cmd(PDU_CMD_IVR_WANT_AGENT); cmd.SetDataInt(1, m_pIvrFlow->id()); cmd.SetDataULong(2, m_pIvrFlow->assoCallId()); cmd.SetDataUInt(3, m_AgentStrategy); cmd.SetDataUInt(4, nGroup); cmd.SetDataInt(5, nVipLevel); CString Data; if (m_pIvrFlow->findVarValue(SYSTEM_VAR_CALLER, Data)) cmd.SetDataString(6, Data); if(m_pIvrFlow->findVarValue(m_AgentVar, Data)) cmd.SetDataString(7, Data); if( !CNetworkIvr::GetInstance().send(cmd)) { ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错, 向CTI发送消息失败"), Info); return CELL_OP_SEND_ERROR; } return CELL_OP_WAIT_FOR; } /***************************************************************** **【函数名称】 copy **【函数功能】 拷贝自身 **【参数】 **【返回值】 拷贝副本 ****************************************************************/ CCellBase * CCellQueue::copy( void ) { CCellBase * pCellBase = new CCellQueue(*this); return pCellBase; } /***************************************************************** **【函数名称】 fillData **【函数功能】 节点解析,填充数据 **【参数】 Provider:数据提供器 **【返回值】 成功true,失败false ****************************************************************/ bool CCellQueue::fillData( IFlowDataProvider& Provider ) { CString Data; do { if(!Provider.getData(CELL_ATTRIBUTE_POS, Data)) { Data = _T("节点号"); break; } else { sscanf_s(Data, _T("%d"), &m_Pos); if(m_Pos < 1) { Data = _T("节点号"); break; } } if(!Provider.getData(CELL_ATTRIBUTE_STRATEGY, Data)) { Data = _T("座席分配策略"); break; } else { sscanf_s(Data, _T("%d"), &m_AgentStrategy); if(m_AgentStrategy < AGENT_STRATEGY_LOOP || m_AgentStrategy > AGENT_STRATEGY_LESS_SKILL) { Data = _T("座席分配策略"); break; } } if(!Provider.getData(CELL_ATTRIBUTE_VIP_LEVEL_TYPE, Data)) { Data = _T("VIP数据类型"); break; } else { sscanf_s(Data, _T("%d"), &m_VipLevelType); if(m_VipLevelType != CELL_DATA_VAR && m_VipLevelType != CELL_DATA_VAL) { Data = _T("VIP数据类型"); break; } } if(!Provider.getData(CELL_ATTRIBUTE_VIP_LEVEL, m_VipLevel)) { Data = _T("VIP级别"); break; } if(!Provider.getData(CELL_ATTRIBUTE_GROUP_TYPE, Data)) { Data = _T("座席组数据类型"); break; } else { sscanf_s(Data, _T("%d"), &m_GroupType); if(m_GroupType != CELL_DATA_VAR && m_GroupType != CELL_DATA_VAL) { Data = _T("座席组数据类型"); break; } } if(!Provider.getData(CELL_ATTRIBUTE_GROUP, m_SpecifiedGroup)) { Data = _T("指定座席组"); break; } if(!Provider.getData(CELL_ATTRIBUTE_AGENT_VAR, m_AgentVar)) { Data = _T("座席工号存储变量"); break; } if(!Provider.getData(CELL_ATTRIBUTE_EXTEN_VAR, m_ExtenVar)) { Data = _T("座席分机存储变量"); break; } if(!Provider.getData(CELL_ATTRIBUTE_NO_AGENT_POS, Data)) { Data = _T("无座席跳转节点"); break; } else { sscanf_s(Data, _T("%d"), &m_NoAgentPos); if(m_NoAgentPos < 1) { Data = _T("无座席跳转节点"); break; } } if(!Provider.getData(CELL_ATTRIBUTE_NO_FREE_POS, Data)) { Data = _T("无空闲座席跳转节点"); break; } else { sscanf_s(Data, _T("%d"), &m_NoFreePos); if(m_NoFreePos < 1) { Data = _T("无空闲座席跳转节点"); break; } } if(!Provider.getData(CELL_ATTRIBUTE_SUCCESS_POS, Data)) { Data = _T("成功跳转节点"); break; } else { sscanf_s(Data, _T("%d"), &m_SuccessPos); if(m_SuccessPos < 1) { Data = _T("成功跳转节点"); break; } } if(!Provider.getData(CELL_ATTRIBUTE_HANGUP_POS, Data)) { Data = _T("挂机跳转节点"); break; } else { sscanf_s(Data, _T("%d"), &m_HangUpPos); if(m_HangUpPos < 1) { Data = _T("挂机跳转节点"); break; } } Provider.getData(CELL_ATTRIBUTE_NOTE, m_Note); return true; } while (false); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{Cell}: 节点[%s]解析失败, '%s'错误"), CELL_NAME_QUEUE, Data); return false; } /***************************************************************** **【函数名称】 onOpResultReturn **【函数功能】 处理PDU命令 **【参数】 a_pPduEntity:PDU命令 **【返回值】 下一个节点编号 ****************************************************************/ int CCellQueue::onOpResultReturn( CPduEntity *a_pPduEntity ) { CString Info; _getCellInfo(Info); if(a_pPduEntity->GetIsExecReturn() && a_pPduEntity->GetCmdType() == PDU_CMD_IVR_WANT_AGENT) { if(a_pPduEntity->GetDataBool(0)) { CString strExt; strExt.Format(_T("%u"), a_pPduEntity->GetDataUInt(10)); m_pIvrFlow->addVar(m_ExtenVar, strExt); CString strAgentNum; strAgentNum.Format(_T("%u"), a_pPduEntity->GetDataUInt(9)); m_pIvrFlow->addVar(m_AgentVar, strAgentNum); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}: 节点[%s]执行成功, 分机[%s], 工号[%s]"), Info, strExt, strAgentNum); return m_SuccessPos; } else { if(a_pPduEntity->GetDataUInt(8) == QUEUE_AGENT_FAILED_NO_AGENT) { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 节点[%s]执行失败, 没有登录坐席"), Info); return m_NoAgentPos; } else { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 节点[%s]执行失败, 没有空闲坐席"), Info); return m_NoFreePos; } } } // 挂机命令 if(a_pPduEntity->GetCmdType() == PDU_CMD_CTI_IVR_HANGUP) { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}; 节点[%s]执行结束, 收到挂机消息"), Info); return m_HangUpPos; } ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 节点[%s]执行异常, 收到异常PDU"), Info); return CELL_OP_ERROR; }