| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- #include "StdAfx.h"
- #include "CallDetail.h"
- #include "ICdr.h"
- #include "LineHolder.h"
- #include "LogicLine.h"
- #include "CdrConference.h"
- #include "CdrExtCallIn.h"
- #include "CdrExtCallOut.h"
- #include "CdrFax.h"
- #include "Record.h"
- #include "CdrInstead.h"
- #include "CdrIvrCallOut.h"
- #include "CdrTransfer.h"
- #include "CdrTrunkCallIn.h"
- #include "StatisticsMgr.h"
- CCallDetail::CCallDetail(ULONG CallId) : m_CallId(CallId), m_ActionId(0), m_FinalExt(0), m_GrubExt(0), m_PostProcessing(false)
- {
- }
- CCallDetail::~CCallDetail(void)
- {
- }
- /*****************************************************************
- **【函数名称】 __createCdr
- **【函数功能】 创建呼叫明细记录
- **【参数】
- **【返回值】
- *****************************************************************/
- ICdr* CCallDetail::__createCdr( REP_EVENT Event, UINT HostLine )
- {
- // 添加一个明细记录
- ICdr* pCdr = NULL;
- switch (Event)
- {
- case REP_EVENT_TRUNK_CALL_IN: // 中继呼入
- {
- pCdr = new CCdrTrunkCallIn(m_CallId, ++m_ActionId, HostLine);
- }
- break;
- case REP_EVENT_EXT_CALL_OUT: // 坐席呼出
- {
- pCdr = new CCdrExtCallOut(m_CallId, ++m_ActionId, HostLine);
- }
- break;
- case REP_EVENT_EXT_CALL_IN: // 坐席呼入
- {
- //如果操作ID不递增,在坐席接听超时再次重复转坐席时
- //会出现数据库插入数据错误(主键重复)
- pCdr = new CCdrExtCallIn(m_CallId, ++m_ActionId, HostLine);
- }
- break;
- case REP_EVENT_IVR_CALL_OUT: // IVR自动外呼
- {
- pCdr = new CCdrIvrCallOut(m_CallId, ++m_ActionId, HostLine);
- }
- break;
- case REP_EVENT_TRANSFER: // 转移
- {
- pCdr = new CCdrTransfer(m_CallId, ++m_ActionId, HostLine);
- }
- break;
- case REP_EVENT_CONFERENCE: // 会议
- {
- pCdr = new CCdrConference(m_CallId, ++m_ActionId, HostLine);
- }
- break;
- case REP_EVENT_INSTEAD: // 代接
- {
- pCdr = new CCdrInstead(m_CallId, ++m_ActionId, HostLine);
- }
- break;
- case REP_EVENT_FAX_BEGIN: // 收/发传真开始
- {
- // 收发传真时的ActionID,未严格按照坐席操作时序分配,默认与上一个操作同步
- // 如需严格控制ActionID赋值的正确性,需要建立操作关联
- // 其实收发传真表记录ActionID没什么用,有CallID和HostLine即可
- pCdr = new CCdrFax(m_CallId, m_ActionId, HostLine);
- }
- break;
- default:
- break;
- } // end switch
- // 返回表对象指针
- ASSERT(pCdr != NULL);
- return pCdr;
- }
- /*****************************************************************
- **【函数名称】 end
- **【函数功能】 结束呼叫统计过程
- **【参数】
- **【返回值】
- *****************************************************************/
- void CCallDetail::end( void )
- {
- ICdr* pCdr = NULL;
- POSITION pos = m_CdrList.GetHeadPosition();
- // 本呼叫中的统计记录全部提交数据, 然后销毁表实体
- while (pos != NULL)
- {
- pCdr = m_CdrList.GetNext(pos);
- // 写入数据
- ASSERT(pCdr != NULL);
- pCdr->toSql();
- // 销毁表实体
- delete pCdr;
- pCdr = NULL;
- } // end while
- }
- /*****************************************************************
- **【函数名称】 onCallDetail
- **【函数功能】 统计事件响应
- **【参数】 CallId CallID
- Event 统计事件
- HostLine 主控线路
- lpParam 统计信息
- **【返回值】
- *****************************************************************/
- void CCallDetail::onCallDetail( ULONG CallId, REP_EVENT Event, UINT HostLine, void* lpParam )
- {
- // 是否需要添加新表
- if (Event <= REP_EVENT_TURN_IVR)
- {
- ICdr* pCdr = __createCdr(Event, HostLine);
- m_CdrList.AddTail(pCdr);
- pCdr->onCallDetail(Event, HostLine, lpParam);
- }
- else
- {
- // by 这里解决关于中继表缺少的内线通话状态下的数据 2020/1/8
- // 统计事件分发
- POSITION pos = m_CdrList.GetHeadPosition();
- ICdr* pCdr = NULL;
-
- while (pos != NULL)
- {
- pCdr = m_CdrList.GetNext(pos);
- pCdr->onCallDetail(Event, HostLine, lpParam);
- } // end while
-
-
- }
- // 根据事件判断是否需要进行话后处理
- switch(Event)
- {
- case REP_EVENT_TRUNK_CALL_IN: // 外线呼入
- m_PostProcessing = true;
- break;
- case REP_EVENT_EXT_CALL_OUT: // 坐席外呼
- {
- T_EvtExtCallOut* tEvent = (T_EvtExtCallOut*)lpParam;
- if (tEvent->nPeerLineType == 1)
- m_PostProcessing = true;
- }
- break;
- case REP_EVENT_TRANSFER: // 转移或者协商转移
- {
- T_EvtTransfer* tEvent = (T_EvtTransfer*)lpParam;
- if (tEvent->nPeerLineType == 1)
- m_PostProcessing = true;
- }
- break;
- case REP_EVENT_CONFERENCE:
- m_PostProcessing = false;
- break;
- // 在转座席状态发生改变的情况下更新接通的时间 by 2020/1/8
- // 在分机呼入状态下更新中继入表中的分机号以及工号
- // 开始的工号
- case REP_EVENT_TURN_AGENT:
- {
-
- CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(HostLine);
- T_EvtStateChanged repInfo;
- repInfo.nLineState = INNER_STATE_TALKING;
- repInfo.nAgentId = pLine->getAgentNum();
- CStatisticsMgr::GetInstance().onCallDetail(m_CallId, REP_EVENT_STATE_CHANGED, HostLine, &repInfo);
- CString RectrunkFile = "";
- CString RecFile = "";
- RectrunkFile = CRecord::GetInstance().recordTrunk(pLine,RecFile);
-
- // 需要向座席发送录音消息
- // 统计 REP_EVENT_REC_BEGIN
- T_EvtRecBegin repRecInfo;
- memset(&repRecInfo, 0, sizeof(repRecInfo));
- lstrcpy(repRecInfo.szFileName, RectrunkFile);
- UINT lineTemp = pLine->lineId();
- lineTemp--;
- CStatisticsMgr::GetInstance().onCallDetail(m_CallId, REP_EVENT_REC_BEGIN, lineTemp, &repRecInfo);
- }
- break;
- case REP_EVENT_STATE_CHANGED: // 线路变化事件
- {
- T_EvtStateChanged* tEvtState = (T_EvtStateChanged*)lpParam;
- if (tEvtState->nLineState == INNER_STATE_TALKING)
- {
- CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(HostLine);
-
- if (pLine->opType() == PDU_CMD_AGENT_MONI_LISTEN) // 监听线路不进行话后处理
- {
- }
- else if (pLine->opType() == PDU_CMD_AGENT_MONI_INTERCEPT) // 强截
- {
- m_GrubExt = HostLine;
- }
- else
- {
- m_HostLineSet.insert(HostLine);
- }
- }
- else if (tEvtState->nLineState == INNER_STATE_FREE)
- {
-
- if (m_HostLineSet.size() == 1)
- {
- m_FinalExt = m_PostProcessing ? *m_HostLineSet.begin() : 0;
- }
- if (m_GrubExt == HostLine)
- {
- m_FinalExt = m_PostProcessing ? m_GrubExt : 0; // 设置强截的话后处理
- m_GrubExt = 0;
- }
- m_HostLineSet.erase(HostLine);
- }
-
- }
- break;
- default:
- break;
- }
- }
|