中航光电的中间件仓库

CallDetail.cpp 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #include "StdAfx.h"
  2. #include "CallDetail.h"
  3. #include "ICdr.h"
  4. #include "LineHolder.h"
  5. #include "LogicLine.h"
  6. #include "CdrConference.h"
  7. #include "CdrExtCallIn.h"
  8. #include "CdrExtCallOut.h"
  9. #include "CdrFax.h"
  10. #include "CdrInstead.h"
  11. #include "CdrIvrCallOut.h"
  12. #include "CdrTransfer.h"
  13. #include "CdrTrunkCallIn.h"
  14. CCallDetail::CCallDetail(ULONG CallId) : m_CallId(CallId), m_ActionId(0), m_FinalExt(0), m_CurExt(0), m_GrubExt(0), m_PostProcessing(false)
  15. {
  16. }
  17. CCallDetail::~CCallDetail(void)
  18. {
  19. }
  20. /*****************************************************************
  21. **【函数名称】 __createCdr
  22. **【函数功能】 创建呼叫明细记录
  23. **【参数】
  24. **【返回值】
  25. *****************************************************************/
  26. ICdr* CCallDetail::__createCdr( REP_EVENT Event, UINT HostLine )
  27. {
  28. // 添加一个明细记录
  29. ICdr* pCdr = NULL;
  30. switch (Event)
  31. {
  32. case REP_EVENT_TRUNK_CALL_IN:
  33. {
  34. pCdr = new CCdrTrunkCallIn(m_CallId, ++m_ActionId, HostLine);
  35. }
  36. break;
  37. case REP_EVENT_EXT_CALL_OUT:
  38. {
  39. pCdr = new CCdrExtCallOut(m_CallId, ++m_ActionId, HostLine);
  40. }
  41. break;
  42. case REP_EVENT_EXT_CALL_IN:
  43. {
  44. pCdr = findCallCdr(REP_EVENT_EXT_CALL_IN, HostLine);
  45. if (pCdr == NULL) {
  46. pCdr = new CCdrExtCallIn(m_CallId, ++m_ActionId, HostLine);
  47. }
  48. else {
  49. return NULL;
  50. }
  51. }
  52. break;
  53. case REP_EVENT_IVR_CALL_OUT:
  54. {
  55. pCdr = new CCdrIvrCallOut(m_CallId, ++m_ActionId, HostLine);
  56. }
  57. break;
  58. case REP_EVENT_TRANSFER:
  59. {
  60. pCdr = new CCdrTransfer(m_CallId, ++m_ActionId, HostLine);
  61. }
  62. break;
  63. case REP_EVENT_CONFERENCE:
  64. {
  65. pCdr = new CCdrConference(m_CallId, ++m_ActionId, HostLine);
  66. }
  67. break;
  68. case REP_EVENT_INSTEAD:
  69. {
  70. pCdr = new CCdrInstead(m_CallId, ++m_ActionId, HostLine);
  71. }
  72. break;
  73. case REP_EVENT_FAX_BEGIN:
  74. {
  75. // 收发传真时的ActionID,未严格按照坐席操作时序分配,默认与上一个操作同步
  76. // 如需严格控制ActionID赋值的正确性,需要建立操作关联
  77. // 其实收发传真表记录ActionID没什么用,有CallID和HostLine即可
  78. pCdr = new CCdrFax(m_CallId, m_ActionId, HostLine);
  79. }
  80. break;
  81. default:
  82. break;
  83. } // end switch
  84. // 返回表对象指针
  85. ASSERT(pCdr != NULL);
  86. return pCdr;
  87. }
  88. /*****************************************************************
  89. **【函数名称】 end
  90. **【函数功能】 结束呼叫统计过程
  91. **【参数】
  92. **【返回值】
  93. *****************************************************************/
  94. void CCallDetail::end( void )
  95. {
  96. // 本呼叫中的统计记录全部提交数据, 然后销毁表实体
  97. while (m_CdrList.GetCount() > 0)
  98. {
  99. POSITION posIndex = m_CdrList.GetHeadPosition();
  100. ICdr* pCdr = m_CdrList.GetAt( posIndex );
  101. if (NULL != pCdr) {
  102. pCdr->toSql();
  103. delete pCdr;
  104. pCdr = NULL;
  105. m_CdrList.RemoveAt( posIndex );
  106. }
  107. } // end while
  108. }
  109. /*****************************************************************
  110. **【函数名称】 onCallDetail
  111. **【函数功能】 统计事件响应
  112. **【参数】 CallId CallID
  113. Event 统计事件
  114. HostLine 主控线路
  115. lpParam 统计信息
  116. **【返回值】
  117. *****************************************************************/
  118. void CCallDetail::onCallDetail( ULONG CallId, REP_EVENT Event, UINT HostLine, void* lpParam )
  119. {
  120. // 是否需要添加新表
  121. if (Event <= REP_EVENT_TURN_IVR)
  122. {
  123. ICdr* pCdr = __createCdr(Event, HostLine);
  124. if (NULL != pCdr) {
  125. m_CdrList.AddTail(pCdr);
  126. pCdr->onCallDetail(Event, HostLine, lpParam);
  127. }
  128. }
  129. else
  130. {
  131. // 统计事件分发
  132. POSITION pos = m_CdrList.GetHeadPosition();
  133. ICdr* pCdr = NULL;
  134. while (pos != NULL)
  135. {
  136. pCdr = m_CdrList.GetNext(pos);
  137. if (pCdr != NULL)
  138. pCdr->onCallDetail(Event, HostLine, lpParam);
  139. } // end while
  140. }
  141. // 根据事件判断是否需要进行话后处理
  142. switch(Event)
  143. {
  144. case REP_EVENT_TRUNK_CALL_IN: // 外线呼入
  145. m_PostProcessing = true;
  146. break;
  147. case REP_EVENT_EXT_CALL_OUT: // 坐席外呼
  148. {
  149. T_EvtExtCallOut* tEvent = (T_EvtExtCallOut*)lpParam;
  150. if (tEvent->nPeerLineType == 1)
  151. m_PostProcessing = true;
  152. }
  153. break;
  154. case REP_EVENT_TRANSFER: // 转移或者协商转移
  155. {
  156. T_EvtTransfer* tEvent = (T_EvtTransfer*)lpParam;
  157. if (tEvent->nPeerLineType == 1)
  158. m_PostProcessing = true;
  159. }
  160. break;
  161. case REP_EVENT_CONFERENCE:
  162. m_PostProcessing = false;
  163. break;
  164. case REP_EVENT_STATE_CHANGED: // 线路变化事件
  165. {
  166. T_EvtStateChanged* tEvtState = (T_EvtStateChanged*)lpParam;
  167. if (tEvtState->nLineState == INNER_STATE_TALKING)
  168. {
  169. CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(HostLine);
  170. if (pLine->opType() == PDU_CMD_AGENT_MONI_LISTEN) // 监听线路不进行话后处理
  171. {
  172. }
  173. else if (pLine->opType() == PDU_CMD_AGENT_MONI_INTERCEPT) // 强截
  174. {
  175. m_GrubExt = HostLine;
  176. }
  177. else
  178. {
  179. m_HostLineSet.insert(HostLine);
  180. }
  181. }
  182. else if (tEvtState->nLineState == INNER_STATE_FREE)
  183. {
  184. if (m_HostLineSet.size() == 1)
  185. {
  186. m_FinalExt = m_PostProcessing ? *m_HostLineSet.begin() : 0;
  187. }
  188. if (m_GrubExt == HostLine)
  189. {
  190. m_FinalExt = m_PostProcessing ? m_GrubExt : 0; // 设置强截的话后处理
  191. m_GrubExt = 0;
  192. }
  193. m_HostLineSet.erase(HostLine);
  194. }
  195. }
  196. break;
  197. default:
  198. break;
  199. }
  200. }
  201. ICdr* CCallDetail::findCallCdr(REP_EVENT Event, UINT HostLine) {
  202. ICdr* pCdr = NULL;
  203. POSITION pos = m_CdrList.GetHeadPosition();
  204. while (pos != NULL)
  205. {
  206. ICdr* pCdrTmp = m_CdrList.GetNext(pos);
  207. if (pCdrTmp != NULL)
  208. {
  209. if ( (REP_EVENT_EXT_CALL_IN == (pCdrTmp->m_nEventId)) && (HostLine == m_CurExt)) {
  210. pCdr = pCdrTmp;
  211. break;
  212. }
  213. }
  214. }
  215. if (NULL == pCdr) {
  216. m_CurExt = HostLine;
  217. }
  218. return pCdr;
  219. }