中间件底层,websocket

CdrExtCallIn.cpp 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. #include "StdAfx.h"
  2. #include "CdrExtCallIn.h"
  3. #include "SqlWriter.h"
  4. CCdrExtCallIn::CCdrExtCallIn(ULONG uCallId, UINT nActionId, UINT nHostLine) : m_uCallId(uCallId), m_nActionId(nActionId), m_nHostLine(nHostLine)
  5. {
  6. m_bIsActive = TRUE;
  7. m_nCallType = 0;
  8. m_nPeerLineType = 0;
  9. m_nCallerAgentId = 0;
  10. m_strCallerNum = _T("");
  11. m_nCalleeAgentId = 0;
  12. m_strCalleeNum = _T("");
  13. m_nTimeAlerting = 0;
  14. m_nIsAnswer = 0;
  15. m_nPeriodAlerting = 0;
  16. m_nTimeAnswer = 0;
  17. m_strRecFileName = _T("");
  18. m_nTimeHangUp = 0;
  19. m_nPeriodTalking = 0;
  20. m_strCalleeGroup = "";
  21. }
  22. CCdrExtCallIn::~CCdrExtCallIn(void)
  23. {
  24. }
  25. /*****************************************************************
  26. **【函数名称】 __verifyData
  27. **【函数功能】 数据校验
  28. **【参数】
  29. **【返回值】
  30. *****************************************************************/
  31. BOOL CCdrExtCallIn::__verifyData()
  32. {
  33. return TRUE;
  34. }
  35. /*****************************************************************
  36. **【函数名称】 OnLineStateChanged
  37. **【函数功能】 线路状态变化响应
  38. **【参数】 nHostLine 主控线路
  39. tEvtState 线路状态变化事件
  40. **【返回值】
  41. *****************************************************************/
  42. void CCdrExtCallIn::__onLineStateChanged( UINT nHostLine, T_EvtStateChanged* tEvtState )
  43. {
  44. // 接收并处理 ExtCallIn表 需要的线路状态
  45. switch (tEvtState->nLineState)
  46. {
  47. case INNER_STATE_TALKING: // 内线通话中
  48. {
  49. if (m_nHostLine == nHostLine && m_nIsAnswer == 0)
  50. {
  51. m_nIsAnswer = 1; // 坐席应答
  52. m_nTimeAnswer = time(NULL); // 应答时间
  53. m_nPeriodAlerting = (UINT)(m_nTimeAnswer - m_nTimeAlerting); // 振铃时长
  54. }
  55. }
  56. break;
  57. case INNER_STATE_FREE: // 内线挂机
  58. {
  59. if (m_nHostLine == nHostLine)
  60. {
  61. m_nTimeHangUp = time(NULL); // 挂机时间
  62. if (m_nIsAnswer == 0) // 未接听挂机
  63. {
  64. m_nPeriodTalking = 0;
  65. m_nPeriodAlerting = (UINT)(m_nTimeHangUp - m_nTimeAlerting);
  66. }
  67. else
  68. {
  69. m_nPeriodTalking = (UINT)(m_nTimeHangUp - m_nTimeAnswer); // 通话时长
  70. }
  71. // 更新数据
  72. toSql();
  73. }
  74. }
  75. break;
  76. default:
  77. break;
  78. } // end switch
  79. }
  80. /*****************************************************************
  81. **【函数名称】 onCallDetail
  82. **【函数功能】 统计事件响应
  83. **【参数】 nEvent 统计事件
  84. nHostLine 主控线路
  85. lpParam 统计信息
  86. **【返回值】
  87. *****************************************************************/
  88. void CCdrExtCallIn::onCallDetail( REP_EVENT nEvent, UINT nHostLine, void* lpParam )
  89. {
  90. // 接收并处理 ExtCallIn表 需要的事件
  91. switch (nEvent)
  92. {
  93. case REP_EVENT_EXT_CALL_IN: // 坐席呼入事件
  94. {
  95. if (nHostLine == m_nHostLine)
  96. {
  97. T_EvtExtCallIn* tEvent = (T_EvtExtCallIn*)lpParam;
  98. m_nCallType = tEvent->nCallType; // 呼入类型
  99. m_nPeerLineType = tEvent->nPeerLineType; // 对端线路类型
  100. m_nCallerAgentId = tEvent->nCallerAgentId; // 主叫坐席工号
  101. m_strCallerNum = tEvent->szCallerNum; // 主叫号码
  102. m_nCalleeAgentId = tEvent->nCalleeAgentId; // 被叫坐席工号
  103. m_strCalleeGroup.Format("%s",tEvent->nCalleeAgentGroup); // 被叫坐席组号 2021-11-29添加
  104. m_strCalleeNum.Format(_T("%d"), nHostLine); // 被叫号码
  105. m_nTimeAlerting = time(NULL); // 来电振铃时间
  106. }
  107. }
  108. break;
  109. case REP_EVENT_REC_BEGIN: // 录音开始事件
  110. {
  111. if (m_nHostLine == nHostLine)
  112. {
  113. T_EvtRecBegin* tEvent = (T_EvtRecBegin*)lpParam;
  114. m_strRecFileName = tEvent->szFileName; // 录音文件路径
  115. }
  116. }
  117. break;
  118. case REP_EVENT_HANG_UP: // 挂机事件
  119. {
  120. if (m_nHostLine == nHostLine)
  121. {
  122. m_nTimeHangUp = time(NULL); // 坐席挂机时间
  123. m_nPeriodTalking = (m_nIsAnswer == 1) ? (UINT)(m_nTimeHangUp - m_nTimeAnswer) : 0; // 通话时长
  124. // 更新数据
  125. toSql();
  126. }
  127. }
  128. break;
  129. case REP_EVENT_STATE_CHANGED: // 线路变化事件
  130. {
  131. T_EvtStateChanged* tEvtState = (T_EvtStateChanged*)lpParam;
  132. __onLineStateChanged(nHostLine, tEvtState);
  133. }
  134. break;
  135. default:
  136. break;
  137. } // end switch
  138. }
  139. /*****************************************************************
  140. **【函数名称】 toSql
  141. **【函数功能】 更新数据库表数据
  142. **【参数】
  143. **【返回值】
  144. *****************************************************************/
  145. void CCdrExtCallIn::toSql()
  146. {
  147. // 表被关闭,不再更新数据
  148. if (!m_bIsActive) return;
  149. // 数据校验(有关键数据未填写且不适合自动填充时,返回失败)
  150. if (__verifyData())
  151. m_bIsActive = FALSE;
  152. else
  153. return;
  154. // 写入 rep_host 主表
  155. CSqlWriter& Writer = CSqlWriter::GetInstance();
  156. CString strSql = _T("");
  157. if (DB_Oracle == IOtlConnection::getInstance()->GetDatabaseType()) {
  158. strSql.Format(_T("INSERT INTO REP_HOST (CALLID, ACTIONID, CALLTYPEOPTYPE, HOSTLINE, CALLERNUM, CALLEENUM, TIMECONNECTED, TIMEHANGUP) VALUES (%lu, %d, %d, %d, '%s', '%s', %s, %s)"),
  159. m_uCallId,
  160. m_nActionId,
  161. REP_EVENT_EXT_CALL_IN,
  162. m_nHostLine,
  163. m_strCallerNum,
  164. m_strCalleeNum,
  165. FormatTime(m_nTimeAnswer),
  166. FormatTime(m_nTimeHangUp)
  167. );
  168. }
  169. else {
  170. strSql.Format(_T("INSERT INTO rep_host (CallID, ActionID, CallTypeOpType, HostLine, CallerNum, CalleeNum, TimeConnected, TimeHangUp) VALUES (%lu, %d, %d, %d, '%s', '%s', %s, %s)"),
  171. m_uCallId,
  172. m_nActionId,
  173. REP_EVENT_EXT_CALL_IN,
  174. m_nHostLine,
  175. m_strCallerNum,
  176. m_strCalleeNum,
  177. FormatTime(m_nTimeAnswer),
  178. FormatTime(m_nTimeHangUp)
  179. );
  180. }
  181. Writer.addSql(strSql); // 在坐席未接听的情况下重复转坐席 actionID累加,相当于多次呼入,所以主表同样插入记录
  182. // 写入 rep_ext_call_in 坐席呼入子表
  183. if (DB_Oracle == IOtlConnection::getInstance()->GetDatabaseType()) {
  184. strSql.Format(_T("INSERT INTO REP_EXT_CALL_IN (CALLID,ACTIONID,CALLTYPE,PEERLINETYPE,CALLERAGENTID,CALLERNUM,CALLEEAGENTID, CALLEENUM,TIMEALERTING,PERIODALERTING,ISANSWER,TIMEANSWER,RECFILENAME,TIMEHANGUP,PERIODTALKING,GROUPID) VALUES (%lu, %d, %d, %d, %d, '%s', %d, '%s', %s, %d, %d, %s, '%s', %s, %d,'%s')"),
  185. m_uCallId,
  186. m_nActionId,
  187. m_nCallType,
  188. m_nPeerLineType,
  189. m_nCallerAgentId,
  190. m_strCallerNum,
  191. m_nCalleeAgentId,
  192. m_strCalleeNum,
  193. FormatTime(m_nTimeAlerting),
  194. m_nPeriodAlerting,
  195. m_nIsAnswer,
  196. FormatTime(m_nTimeAnswer),
  197. m_strRecFileName,
  198. FormatTime(m_nTimeHangUp),
  199. m_nPeriodTalking,
  200. m_strCalleeGroup
  201. );
  202. }else {
  203. strSql.Format(_T("INSERT INTO rep_ext_call_in (CallID,ActionID,CallType,PeerLineType,CallerAgentID,CallerNum,CalleeAgentID,\
  204. CalleeNum,TimeAlerting,PeriodAlerting,IsAnswer,TimeAnswer,RecFileName,TimeHangUp,PeriodTalking,GroupId)\
  205. VALUES (%lu, %d, %d, %d, %d, '%s', %d, '%s', %s, %d, %d, %s, '%s', %s, %d,'%s')"),
  206. m_uCallId,
  207. m_nActionId,
  208. m_nCallType,
  209. m_nPeerLineType,
  210. m_nCallerAgentId,
  211. m_strCallerNum,
  212. m_nCalleeAgentId,
  213. m_strCalleeNum,
  214. FormatTime(m_nTimeAlerting),
  215. m_nPeriodAlerting,
  216. m_nIsAnswer,
  217. FormatTime(m_nTimeAnswer),
  218. m_strRecFileName,
  219. FormatTime(m_nTimeHangUp),
  220. m_nPeriodTalking,
  221. m_strCalleeGroup
  222. );
  223. }
  224. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{CdrExtCallIn}: 分机呼入表插入记录, SQL=%s"), strSql);
  225. Writer.addSql(strSql);
  226. }