升龙物业 老版本 ocx IPO, 加密狗 转值班电话

CallDetail.cpp 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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_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. //如果操作ID不递增,在坐席接听超时再次重复转坐席时
  45. //会出现数据库插入数据错误(主键重复)
  46. pCdr = new CCdrExtCallIn(m_CallId, ++m_ActionId, HostLine);
  47. }
  48. break;
  49. case REP_EVENT_IVR_CALL_OUT: // IVR自动外呼
  50. {
  51. pCdr = new CCdrIvrCallOut(m_CallId, ++m_ActionId, HostLine);
  52. }
  53. break;
  54. case REP_EVENT_TRANSFER: // 转移
  55. {
  56. pCdr = new CCdrTransfer(m_CallId, ++m_ActionId, HostLine);
  57. }
  58. break;
  59. case REP_EVENT_CONFERENCE: // 会议
  60. {
  61. pCdr = new CCdrConference(m_CallId, ++m_ActionId, HostLine);
  62. }
  63. break;
  64. case REP_EVENT_INSTEAD: // 代接
  65. {
  66. pCdr = new CCdrInstead(m_CallId, ++m_ActionId, HostLine);
  67. }
  68. break;
  69. case REP_EVENT_FAX_BEGIN: // 收/发传真开始
  70. {
  71. // 收发传真时的ActionID,未严格按照坐席操作时序分配,默认与上一个操作同步
  72. // 如需严格控制ActionID赋值的正确性,需要建立操作关联
  73. // 其实收发传真表记录ActionID没什么用,有CallID和HostLine即可
  74. pCdr = new CCdrFax(m_CallId, m_ActionId, HostLine);
  75. }
  76. break;
  77. default:
  78. break;
  79. } // end switch
  80. // 返回表对象指针
  81. ASSERT(pCdr != NULL);
  82. return pCdr;
  83. }
  84. /*****************************************************************
  85. **【函数名称】 end
  86. **【函数功能】 结束呼叫统计过程
  87. **【参数】
  88. **【返回值】
  89. *****************************************************************/
  90. void CCallDetail::end( void )
  91. {
  92. ICdr* pCdr = NULL;
  93. POSITION pos = m_CdrList.GetHeadPosition();
  94. // 本呼叫中的统计记录全部提交数据, 然后销毁表实体
  95. while (pos != NULL)
  96. {
  97. pCdr = m_CdrList.GetNext(pos);
  98. // 写入数据
  99. ASSERT(pCdr != NULL);
  100. pCdr->toSql();
  101. // 销毁表实体
  102. delete pCdr;
  103. pCdr = NULL;
  104. } // end while
  105. }
  106. /*****************************************************************
  107. **【函数名称】 onCallDetail
  108. **【函数功能】 统计事件响应
  109. **【参数】 CallId CallID
  110. Event 统计事件
  111. HostLine 主控线路
  112. lpParam 统计信息
  113. **【返回值】
  114. *****************************************************************/
  115. void CCallDetail::onCallDetail( ULONG CallId, REP_EVENT Event, UINT HostLine, void* lpParam )
  116. {
  117. // 是否需要添加新表
  118. if (Event <= REP_EVENT_TURN_IVR)
  119. {
  120. ICdr* pCdr = __createCdr(Event, HostLine);
  121. m_CdrList.AddTail(pCdr);
  122. pCdr->onCallDetail(Event, HostLine, lpParam);
  123. }
  124. else
  125. {
  126. // 统计事件分发
  127. POSITION pos = m_CdrList.GetHeadPosition();
  128. ICdr* pCdr = NULL;
  129. while (pos != NULL)
  130. {
  131. pCdr = m_CdrList.GetNext(pos);
  132. if (pCdr != NULL)
  133. pCdr->onCallDetail(Event, HostLine, lpParam);
  134. } // end while
  135. }
  136. // 根据事件判断是否需要进行话后处理
  137. switch(Event)
  138. {
  139. case REP_EVENT_TRUNK_CALL_IN: // 外线呼入
  140. m_PostProcessing = true;
  141. break;
  142. case REP_EVENT_EXT_CALL_OUT: // 坐席外呼
  143. {
  144. T_EvtExtCallOut* tEvent = (T_EvtExtCallOut*)lpParam;
  145. if (tEvent->nPeerLineType == 1)
  146. m_PostProcessing = true;
  147. }
  148. break;
  149. case REP_EVENT_TRANSFER: // 转移或者协商转移
  150. {
  151. T_EvtTransfer* tEvent = (T_EvtTransfer*)lpParam;
  152. if (tEvent->nPeerLineType == 1)
  153. m_PostProcessing = true;
  154. }
  155. break;
  156. case REP_EVENT_CONFERENCE:
  157. m_PostProcessing = false;
  158. break;
  159. case REP_EVENT_STATE_CHANGED: // 线路变化事件
  160. {
  161. T_EvtStateChanged* tEvtState = (T_EvtStateChanged*)lpParam;
  162. if (tEvtState->nLineState == INNER_STATE_TALKING)
  163. {
  164. CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(HostLine);
  165. if (pLine->opType() == PDU_CMD_AGENT_MONI_LISTEN) // 监听线路不进行话后处理
  166. {
  167. }
  168. else if (pLine->opType() == PDU_CMD_AGENT_MONI_INTERCEPT) // 强截
  169. {
  170. m_GrubExt = HostLine;
  171. }
  172. else
  173. {
  174. m_HostLineSet.insert(HostLine);
  175. }
  176. }
  177. else if (tEvtState->nLineState == INNER_STATE_FREE)
  178. {
  179. if (m_HostLineSet.size() == 1)
  180. {
  181. m_FinalExt = m_PostProcessing ? *m_HostLineSet.begin() : 0;
  182. }
  183. if (m_GrubExt == HostLine)
  184. {
  185. m_FinalExt = m_PostProcessing ? m_GrubExt : 0; // 设置强截的话后处理
  186. m_GrubExt = 0;
  187. }
  188. m_HostLineSet.erase(HostLine);
  189. }
  190. }
  191. break;
  192. default:
  193. break;
  194. }
  195. }