#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; } } if (!Provider.getData(CELL_ATTRIBUTE_QUEUE_LEN_VAR, m_QueueLenVar)) { Data = _T("排队队列长度变量"); m_QueueLenVar = "QueueLen"; //break; ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{Cell}: 节点[%s]解析, '%s'不存在,默认'QueueLen'"), CELL_NAME_QUEUE, Data); } 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 { //QueueLenVar int t_queue_len = a_pPduEntity->GetDataUInt(11); CString strQueueLen; turnToZhNum(t_queue_len, strQueueLen); m_pIvrFlow->addVar(m_QueueLenVar, strQueueLen); if(a_pPduEntity->GetDataUInt(8) == QUEUE_AGENT_FAILED_NO_AGENT) { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 节点[%s]执行失败, 没有登录坐席,队列长[%s]"), Info, strQueueLen); return m_NoAgentPos; } else { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 节点[%s]执行失败, 没有空闲坐席,队列长[%s]"), Info, strQueueLen); 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; } int CCellQueue::turnToZhNumBase(int p_num, CString& p_zh) { if (p_num > 9 || p_num < 0) return 1; switch (p_num) { case 0: p_zh = "零"; break; case 1: p_zh = "一"; break; case 2: p_zh = "二"; break; case 3: p_zh = "三"; break; case 4: p_zh = "四"; break; case 5: p_zh = "五"; break; case 6: p_zh = "六"; break; case 7: p_zh = "七"; break; case 8: p_zh = "八"; break; case 9: p_zh = "九"; break; default: break; } return 0; } int CCellQueue::turnToZhNum(int p_nums, CString& p_zh) { if (p_nums <= 0){ p_zh = "0"; }else if (p_nums > 100) p_nums = 99; if (p_nums < 10) { turnToZhNumBase(p_nums, p_zh); } else { int t_f = p_nums % 10; int t_s = p_nums / 10; CString t_zh; if(t_s != 1) { turnToZhNumBase(t_s, t_zh); p_zh.Append(t_zh); } p_zh.Append("十"); if (t_f != 0) { t_zh.Empty(); turnToZhNumBase(t_f, t_zh); } p_zh.Append(t_zh); } return 0; }