| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511 |
- #include "StdAfx.h"
- #include "Agent.h"
- #include "Config.h"
- #include "SLogic.h"
- #include "AcdCore.h"
- #include "MsgCenter.h"
- #include "NetworkAcd.h"
- CAgent::CAgent(UINT a_AgentID, UINT a_ExtID, LPCTSTR a_GroupID, UINT a_AgentType, UINT a_PostProcessingTime)
- {
- // 网络属性
- CNetworkAcd::GetInstance().getAgentLinkInfo(a_AgentID, m_AgentIp, m_AgentPort);
- // 基本属性
- m_AgentID = a_AgentID;
- m_Exten = a_ExtID;
- m_GroupID = a_GroupID;
- m_AgentType = (AGENT_TYPE)a_AgentType;
- m_State = AGENT_STATE_UNKNOWN;
- m_AssoExtState = INNER_STATE_FREE;
- m_IsRepose = false;
- // 业务属性
- m_AnswerCount = 0;
- m_ReposeCount = 0;
- m_TimeFree = 0;
- m_TimeRepos = 0;
- m_TimeTalk = 0;
- m_TimePostProcessing = (a_PostProcessingTime == 0) ? CConfig::postProcessingTime() : a_PostProcessingTime;
- // 定时器初始化
- m_PollTimer.SetTimedEvent(this, &CAgent::__onTimerPoll);
- m_PollTimer.Start(1000);
- // 通知统计模块座席签入
- __reportLogin();
- // 添加消息可供视图刷新
- CMsgCenter::GetInstance().pushMsg(ACD_MSG_AGENT_STATE_UPDAET, (const PARAM)m_AgentID);
- }
- CAgent::~CAgent(void)
- {
- m_PollTimer.StopSafely();
- m_AgentTimer.StopSafely();
- }
- /*****************************************************************
- **【函数名称】 __reportLogin
- **【函数功能】 签出统计通知
- **【参数】
- **【返回值】
- ****************************************************************/
- void CAgent::__reportLogin()
- {
- // 通知统计模块 REP_EVENT_LOGIN
- T_EvtLogIn repLogin = { 0 };
- repLogin.nAgentID = m_AgentID;
- repLogin.nExtID = m_Exten;
- repLogin.nAgentType = m_AgentType;
- lstrcpy(repLogin.szGroup, m_GroupID);
- lstrcpy(repLogin.szAgentIP, m_AgentIp);
- CSLogic::GetInstance().onSEvent(m_AgentID, REP_EVENT_LOGIN, &repLogin);
- }
- /*****************************************************************
- **【函数名称】 __reportLogout
- **【函数功能】 签出统计通知
- **【参数】 HostAgent: 签出当前座席的主控座席
- **【返回值】
- ****************************************************************/
- void CAgent::__reportLogout( const UINT HostAgent )
- {
- if(m_State == AGENT_STATE_REPOSE )
- __onStatusUpdate(AGENT_STATE_REPOSE, false);
- if( m_State == AGENT_STATE_POST_PROCESSING )
- __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
- // 通知统计模块 REP_EVENT_LOGOUT
- T_EvtLogout repLogout = { 0 };
- repLogout.nLogoutHost = HostAgent;
- repLogout.nTimeFree = m_TimeFree;
- repLogout.nTimeRepose = m_TimeRepos;
- repLogout.nTimeTalk = m_TimeTalk;
- repLogout.nAnswerCount = m_AnswerCount;
- repLogout.nReposeCount = m_ReposeCount;
- CSLogic::GetInstance().onSEvent(m_AgentID, REP_EVENT_LOGOUT, &repLogout);
- }
- /*****************************************************************
- **【函数名称】 __onStatusUpdate
- **【函数功能】 座席状态变更通知
- **【参数】
- **【返回值】
- ****************************************************************/
- void CAgent::__onStatusUpdate( AGENT_STATE State, bool StartFlag )
- {
- T_EvtStatus EvtStatus;
- EvtStatus.State = State;
- EvtStatus.StartFlag = StartFlag;
- CSLogic::GetInstance().onSEvent(m_AgentID, REP_EVENT_STATE, &EvtStatus);
- }
- /*****************************************************************
- **【函数名称】 __reportStatus
- **【函数功能】 通知各方座席当前状态
- **【参数】
- **【返回值】
- ****************************************************************/
- void CAgent::__reportStatus( void )
- {
- // 通知OCX座席当前状态
- CPduEntity Cmd(PDU_CMD_ACD_AGENT_STATE);
- Cmd.SetDataUInt(0, m_Exten);
- Cmd.SetDataUInt(1, m_AgentID);
- Cmd.SetDataUInt(2, m_State);
- CNetworkAcd::GetInstance().send2Agent(m_AgentID, &Cmd);
- // 添加消息可供视图刷新
- CMsgCenter::GetInstance().pushMsg(ACD_MSG_AGENT_STATE_UPDAET, (PARAM)m_AgentID);
- }
- /*****************************************************************
- **【函数名称】 __onTimerPoll
- **【函数功能】 轮询定时器处理
- **【参数】
- **【返回值】
- ****************************************************************/
- void CAgent::__onTimerPoll( void )
- {
- if(m_State == AGENT_STATE_FREE)
- m_TimeFree++;
- else if(m_State == AGENT_STATE_BUSY)
- m_TimeTalk++;
- if(m_IsRepose)
- m_TimeRepos++;
- }
- /*****************************************************************
- **【函数名称】 __onTimerPostProcessing
- **【函数功能】 话后处理时长定时器处理
- **【参数】
- **【返回值】
- ****************************************************************/
- void CAgent::__onTimerPostProcessing( void )
- {
- if(m_State == AGENT_STATE_POST_PROCESSING)
- {
- setState(AGENT_STATE_FREE);
- }
- }
- /*****************************************************************
- **【函数名称】 __onTimerLock
- **【函数功能】 座席被锁定超时处理
- **【参数】
- **【返回值】
- ****************************************************************/
- void CAgent::__onTimerLock( void )
- {
- if(m_State == AGENT_STATE_REQUESTED)
- {
- setState(AGENT_STATE_FREE, true);
- }
- }
- /*****************************************************************
- **【函数名称】 __setTimer
- **【函数功能】 设立定时器
- **【参数】
- **【返回值
- ****************************************************************/
- void CAgent::__setTimer( UINT TimmerId, UINT Elapse )
- {
- if(TimmerId == TIMER_POST_PROCESSING)
- {
- m_AgentTimer.StopSafely();
- m_AgentTimer.SetTimedEvent(this, &CAgent::__onTimerPostProcessing);
- m_AgentTimer.Start(Elapse, false, true, WT_EXECUTEDEFAULT);
- }
- else if(TimmerId == TIMER_LOCK_PERIOD)
- {
- m_AgentTimer.StopSafely();
- m_AgentTimer.SetTimedEvent(this, &CAgent::__onTimerLock);
- m_AgentTimer.Start(Elapse, false, true, WT_EXECUTEDEFAULT);
- }
- else
- {
- ASSERT(FALSE);
- }
- }
- /*****************************************************************
- **【函数名称】 __killTimer
- **【函数功能】 删除定时器
- **【参数】
- **【返回值
- ****************************************************************/
- void CAgent::__killTimer( UINT TimmerId )
- {
- m_AgentTimer.Stop();
- }
- /*****************************************************************
- **【函数名称】 release
- **【函数功能】 清理资源
- **【参数】 HostAgent: 主控制坐席工号
- **【返回值】
- ****************************************************************/
- void CAgent::release( UINT HostAgent )
- {
- m_PollTimer.StopSafely();
- m_AgentTimer.StopSafely();
- // 设置状态为注销
- setState(AGENT_STATE_LOGOUT);
- // 通知统计模块 REP_EVENT_LOGOUT
- __reportLogout(HostAgent);
- // 关闭Agent端SOCKET连接
- CNetworkAcd::GetInstance().shutDownAgentLink(m_AgentID);
- // 添加消息可供视图刷新
- CMsgCenter::GetInstance().pushMsg(ACD_MSG_AGENT_LOGOUT, (const PARAM)m_AgentID);
- }
- /*****************************************************************
- **【函数名称】 setState
- **【函数功能】 设置座席状态
- **【参数】 a_AgentState:座席当前逻辑状态
- **【返回值】
- ****************************************************************/
- BOOL CAgent::setState( AGENT_STATE a_AgentState, bool IsForce/* = false*/ )
- {
- CSingleLock Locker(&m_Cs4Lock, TRUE);
- switch(a_AgentState)
- {
- case AGENT_STATE_BUSY: // 通话
- {
- switch(m_State)
- {
- case AGENT_STATE_BUSY:
- return TRUE;
- break;
- case AGENT_STATE_REQUESTED:
- __killTimer(TIMER_LOCK_PERIOD);
- break;
- case AGENT_STATE_POST_PROCESSING:
- {
- __killTimer(TIMER_POST_PROCESSING);
- __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
- }
- break;
- case AGENT_STATE_REPOSE:
- {
- m_IsRepose = false;
- __onStatusUpdate(AGENT_STATE_REPOSE, false);
- }
- break;
- case AGENT_STATE_LOGOUT:
- return FALSE;
- break;
- }
- __onStatusUpdate(AGENT_STATE_BUSY, true);
- m_State = AGENT_STATE_BUSY;
- }
- break;
- case AGENT_STATE_REPOSE: // 小休
- {
- switch(m_State)
- {
- case AGENT_STATE_REPOSE:
- return TRUE;
- break;
- case AGENT_STATE_POST_PROCESSING:
- {
- __killTimer(TIMER_POST_PROCESSING);
- __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
- }
- break;
- case AGENT_STATE_BUSY:
- case AGENT_STATE_LOGOUT:
- case AGENT_STATE_REQUESTED:
- return FALSE;
- break;
- }
- m_ReposeCount++;
- m_IsRepose = true;
- m_State = AGENT_STATE_REPOSE;
- // 统计小休开始
- __onStatusUpdate(AGENT_STATE_REPOSE, true);
- }
- break;
- case AGENT_STATE_POST_PROCESSING: // 话后处理
- {
- switch(m_State)
- {
- case AGENT_STATE_POST_PROCESSING:
- return TRUE;
- break;
- case AGENT_STATE_BUSY:
- __onStatusUpdate(AGENT_STATE_BUSY, false);
- break;
- case AGENT_STATE_FREE:
- case AGENT_STATE_REPOSE:
- case AGENT_STATE_REQUESTED:
- case AGENT_STATE_LOGOUT:
- return FALSE;
- break;
- }
- // 统计话后处理开始
- __onStatusUpdate(AGENT_STATE_POST_PROCESSING, true);
- m_State = AGENT_STATE_POST_PROCESSING;
- if (m_TimePostProcessing > 0)
- __setTimer(TIMER_POST_PROCESSING, m_TimePostProcessing * 1000); // 启动话后处理定时器
- }
- break;
- case AGENT_STATE_FREE: // 空闲
- {
- switch(m_State)
- {
- case AGENT_STATE_FREE:
- return TRUE;
- break;
- case AGENT_STATE_BUSY:
- {
- if(IsForce)
- __onStatusUpdate(AGENT_STATE_BUSY, false);
- else
- return FALSE;
- }
- break;
- case AGENT_STATE_POST_PROCESSING:
- {
- __killTimer(TIMER_POST_PROCESSING);
- __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
- }
- break;
- case AGENT_STATE_REPOSE:
- {
- __onStatusUpdate(AGENT_STATE_REPOSE, false);
- m_IsRepose = false;
- }
- break;
- case AGENT_STATE_REQUESTED:
- {
- if(IsForce)
- __killTimer(TIMER_LOCK_PERIOD);
- else
- return FALSE;
- }
- break;
- case AGENT_STATE_LOGOUT:
- return FALSE;
- break;
- }
- m_State = m_IsRepose ? AGENT_STATE_REPOSE : AGENT_STATE_FREE;
- }
- break;
- case AGENT_STATE_REQUESTED: // 被请求
- {
- ASSERT(m_State == AGENT_STATE_FREE);
- switch(m_State)
- {
- case AGENT_STATE_REQUESTED:
- case AGENT_STATE_BUSY:
- case AGENT_STATE_REPOSE:
- case AGENT_STATE_POST_PROCESSING:
- case AGENT_STATE_LOGOUT:
- return FALSE;
- break;
- }
- __setTimer(TIMER_LOCK_PERIOD, CConfig::agentLockedPeriod() * 1000); // 被请求超时处理定时器
- m_State = AGENT_STATE_REQUESTED;
- }
- break;
- default:
- {
- switch(m_State)
- {
- case AGENT_STATE_BUSY:
- __onStatusUpdate(AGENT_STATE_BUSY, false);
- break;
- case AGENT_STATE_POST_PROCESSING:
- {
- __killTimer(TIMER_POST_PROCESSING);
- __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
- }
- break;
- case AGENT_STATE_REPOSE:
- {
- m_IsRepose = false;
- __onStatusUpdate(AGENT_STATE_REPOSE, false);
- }
- break;
- case AGENT_STATE_REQUESTED:
- __killTimer(TIMER_LOCK_PERIOD);
- break;
- }
- m_State = a_AgentState;
- }
- break;
- } // end switch
- // 通知座席当前状态变化
- __reportStatus();
- return TRUE;
- }
- /*****************************************************************
- **【函数名称】 onAssoExtStatusUpdated
- **【函数功能】 关联分机状态更新的处理函数
- **【参数】 a_ExtState:分机当前状态
- Param:附加参数
- **【返回值】
- ****************************************************************/
- void CAgent::onAssoExtStatusUpdated( INNER_STATE a_ExtState, PARAM Param /*= NULL*/ )
- {
- CPduEntity * pCmd = (CPduEntity *)Param;
- m_AssoExtState = a_ExtState;
- switch(a_ExtState)
- {
- case INNER_STATE_ALERTING:
- {
- // 来电振铃时解除请求锁定等状态
- if(m_State == AGENT_STATE_POST_PROCESSING || m_State == AGENT_STATE_REPOSE || m_State == AGENT_STATE_REQUESTED)
- setState(AGENT_STATE_FREE, true);
- }
- break;
- case INNER_STATE_RING_BACK:
- {
- if(m_State == AGENT_STATE_POST_PROCESSING || m_State == AGENT_STATE_REPOSE || m_State == AGENT_STATE_REQUESTED)
- setState(AGENT_STATE_FREE, true);
- }
- break;
- case INNER_STATE_TALKING:
- {
- if(pCmd == NULL || pCmd->GetDataUInt(10) != PDU_CMD_AGENT_MONI_REPLACE) // 如果是代接操作则不记录应答次数
- m_AnswerCount++; // 累计应答计数
- setState(AGENT_STATE_BUSY, true);
- }
- break;
- case INNER_STATE_FREE:
- {
- if(m_State == AGENT_STATE_BUSY)
- {
- ASSERT(pCmd != NULL);
- // 关联线路为非内线,最后通话分机为当前分机,则需要进行话后处理
- if(pCmd != NULL && pCmd->GetDataUInt(7) != DEV_RES_TYPE_EXT && pCmd->GetDataUInt(9) == m_Exten)
- setState(AGENT_STATE_POST_PROCESSING);
- else
- setState(AGENT_STATE_FREE, true);
- }
- else if(m_State == AGENT_STATE_UNKNOWN || m_State == AGENT_STATE_REQUESTED)
- setState(AGENT_STATE_FREE, true);
- }
- break;
- default:
- {
- if(m_State == AGENT_STATE_UNKNOWN)
- setState(AGENT_STATE_FREE);
- }
- break;
- }
- }
- /*****************************************************************
- **【函数名称】 lock
- **【函数功能】 锁定座席
- **【参数】
- **【返回值】
- ****************************************************************/
- BOOL CAgent::lock( void )
- {
- if(isFree())
- return setState(AGENT_STATE_REQUESTED);
- else
- return FALSE;
- }
|