暂无描述

LogicLineExt.cpp 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #include "StdAfx.h"
  2. #include "LogicLineExt.h"
  3. #include "CallSession.h"
  4. #include "SessionHolder.h"
  5. #include "StatisticsMgr.h"
  6. #include "NetworkCti.h"
  7. #include "CtiCore.h"
  8. #include "TaskMgr.h"
  9. CLogicLineExt::CLogicLineExt(UINT ResId) : CLogicLine(ResId), m_AgentId(0), m_FinalExt(0), m_AssoLineType(0), m_HoldRecordFile(_T(""))
  10. {
  11. m_LineStatus = INNER_STATE_FREE;
  12. }
  13. CLogicLineExt::~CLogicLineExt(void)
  14. {
  15. }
  16. /*****************************************************************
  17. **【函数名称】 __telephoneNumBelongsTo
  18. **【函数功能】 获取归属地信息
  19. **【参数】 Number: 来电号码
  20. BelongsTo:输出参数,归属地
  21. **【返回值】
  22. ****************************************************************/
  23. void CLogicLineExt::__telephoneNumBelongsTo(const CString& Number, CString& BelongsTo)
  24. {
  25. // 去掉出局号码进行查询归属地
  26. // Number= Number.Right(Number.GetLength()-1); //屏蔽出局号,该行代码在测试环境中使用
  27. CString SqlFunc = _T("charindex"); // MS SQL SERVER 字符串匹配函数
  28. if (DB_MySQL == IOtlConnection::getInstance()->GetDatabaseType())
  29. SqlFunc = _T("locate"); // MYSQL 字符串匹配函数
  30. CString SQL;
  31. SQL.Format("select * from conf_phone where %s(rtrim(number),'%s') in (1,2)", SqlFunc, Number);
  32. IOtlRecordset* pRD = IOtlConnection::getInstance()->QueryRecords(SQL);
  33. if (NULL == pRD) //判断空值
  34. return;
  35. if (pRD->IsEOF())
  36. {
  37. IOtlRecordset::DestroyInstance(pRD); // 释放记录集
  38. return;
  39. }
  40. CString Province = _T("");
  41. CString City = _T("");
  42. CString Type = _T("");
  43. while (!pRD->IsEOF())
  44. {
  45. pRD->MoveNextRow();
  46. Province = pRD->GetValueStr(_T("Province"));
  47. City = pRD->GetValueStr(_T("City"));
  48. Type = pRD->GetValueStr(_T("Type"));
  49. }
  50. IOtlRecordset::DestroyInstance(pRD); // 释放记录集
  51. BelongsTo = Province.Trim() + _T("-") + City.Trim() + _T("-") + Type.Trim();
  52. }
  53. /*****************************************************************
  54. **【函数名称】 resetLine
  55. **【函数功能】 线路重置
  56. **【参数】
  57. **【返回值】
  58. ****************************************************************/
  59. void CLogicLineExt::resetLine()
  60. {
  61. // 清除线路信息
  62. m_FinalExt = 0;
  63. m_AssoLineType = 0;
  64. m_HoldRecordFile = "";
  65. CLogicLine::resetLine();
  66. }
  67. /*****************************************************************
  68. **【函数名称】 pushLineData2ACD
  69. **【函数功能】 将线路数据发送给ACD
  70. **【参数】
  71. **【返回值】
  72. ****************************************************************/
  73. void CLogicLineExt::pushLineData2ACD()
  74. {
  75. // 通过会话获取线路信息
  76. CString Data = _T("");
  77. CString TrunkNum = _T("");
  78. CCallSession* pSession = CSessionHolder::GetInstance().findSession(m_CallId);
  79. if (pSession != NULL)
  80. {
  81. // 获取随路数据
  82. Data = pSession->data();
  83. // 获取对端线路类型
  84. CLogicLine* pAssoLine = pSession->getAssoLine(this);
  85. if (pAssoLine != NULL)
  86. {
  87. TrunkNum = pAssoLine->calleeNum();
  88. m_AssoLineType = pAssoLine->type();
  89. //2018.5.19分机外线判定
  90. if (m_AssoLineType == DEV_RES_TYPE_VOIP)
  91. {
  92. m_AssoLineType = pAssoLine->typeExtTrunk();
  93. }
  94. // ych
  95. // 2019-9-12 bwj 满意度,分机挂机时不能挂断外线,故屏蔽掉
  96. if (m_LineStatus == INNER_STATE_FREE)
  97. {
  98. #ifdef ISNEEDMYD
  99. CPduEntity CmdTurnIvr(PDU_CMD_CTI_IVR_TURNIVR);
  100. CmdTurnIvr.SetDataULong(2, pAssoLine->callId()); // CallId
  101. CmdTurnIvr.SetDataString(3, pAssoLine->callerNum()); // 主叫
  102. CmdTurnIvr.SetDataString(4, pAssoLine->calleeNum()); // 被叫
  103. CmdTurnIvr.SetDataUInt(5, pAssoLine->lineId()); // 外线Id
  104. CmdTurnIvr.SetDataUInt(6, 0); // 分机Id
  105. CmdTurnIvr.SetDataUInt(7, 0); // IVr节点号
  106. CmdTurnIvr.SetDataString(8, "MYD"); // Ivr文件名
  107. CmdTurnIvr.SetDataString(9, ""); // 随路数据
  108. CmdTurnIvr.SetDataBool(10, false); // 是否返回
  109. BOOL bRet = CNetworkCti::GetInstance().send2IVR(CmdTurnIvr);
  110. // 发送IVR失败,转IVR失败,外线挂机
  111. if (!bRet)
  112. {
  113. LineOpParam pLineOpParam;
  114. memset(&pLineOpParam, 0, sizeof(pLineOpParam));
  115. CCtiCore::GetInstance().getDevLink().exec((long)this, LINE_OP_HANG_UP, pAssoLine->lineId(), &pLineOpParam);
  116. }
  117. #else
  118. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Line}: 当前会话[%d]线路数:%d"), m_CallId, pSession->lineCount());
  119. //if (pSession->lineCount() == 2 && m_AssoLineType == DEV_RES_TYPE_TRUNK) // 对端线路是外线
  120. //{
  121. // CCtiCore::GetInstance().getDevLink().exec((long)-1, LINE_OP_HANG_UP, pAssoLine->lineId(), NULL);
  122. // ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Line}: 座席分机挂机,挂断关联中继线路"));
  123. //}
  124. #endif // ISNEEDMYD
  125. }
  126. }
  127. }
  128. // 发送线路状态变化信息到ACD
  129. CPduEntity Cmd(PDU_CMD_CTI_LINE_STATE);
  130. Cmd.SetDataUInt(0, m_LineId);
  131. Cmd.SetDataUInt(1, m_LineStatus);
  132. Cmd.SetDataULong(2, (m_CallId == 0 ? m_HoldCallId : m_CallId));
  133. Cmd.SetDataUInt(3, m_AgentId);
  134. Cmd.SetDataString(4, m_CallerNum);
  135. Cmd.SetDataString(5, m_CalleeNum);
  136. Cmd.SetDataString(6, Data);
  137. Cmd.SetDataUInt(7, m_AssoLineType);
  138. //if (m_LineStatus == INNER_STATE_ALERTING) //分机振铃事件才送归属地
  139. //{
  140. // CString NumberBelongsTo = _T("");
  141. // __telephoneNumBelongsTo(m_CallerNum, NumberBelongsTo);
  142. // ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("{Line}: 坐席线路来电振铃,来电归属地:%s"), NumberBelongsTo);
  143. // Cmd.SetDataString(8, NumberBelongsTo);
  144. //}
  145. Cmd.SetDataUInt(9, m_FinalExt);
  146. Cmd.SetDataUInt(10, m_CurrentOpType); // 传入当前线路操作类型
  147. Cmd.SetDataInt(11, m_ActionID);
  148. Cmd.SetDataUInt(12, m_IsMeeting); // 2020-01-05 坐席状态,标记是否再会议
  149. Cmd.SetDataString(13, TrunkNum); // 中继号
  150. CNetworkCti::GetInstance().send2ACD(Cmd);
  151. }
  152. /*****************************************************************
  153. **【函数名称】 pushRecord2ACD
  154. **【函数功能】 将录音数据发送给ACD
  155. **【参数】
  156. **【返回值】
  157. ****************************************************************/
  158. void CLogicLineExt::pushRecord2ACD()
  159. {
  160. // 向ACD发送录音文件名
  161. CPduEntity Pdu(PDU_CMD_CTI_RECORD);
  162. Pdu.SetDataUInt(0, m_LineId);
  163. Pdu.SetDataULong(1, m_CallId);
  164. Pdu.SetDataString(2, m_RecordFile);
  165. CNetworkCti::GetInstance().send2ACD(Pdu);
  166. // 显示日志
  167. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("CTI->AGENT, PDU = [线路录音信息], Exten = %d, Agent = %d, RecordFile = %s"),
  168. m_LineId, m_AgentId, m_RecordFile);
  169. }
  170. /*****************************************************************
  171. **【函数名称】 onLineStatusUpdated
  172. **【函数功能】 处理线路状态变化
  173. **【参数】 EvtInfo: 线路资源状态
  174. **【返回值】
  175. ****************************************************************/
  176. void CLogicLineExt::onLineStatusUpdated(const EventResStatus &EvtInfo)
  177. {
  178. if (m_LineStatus == EvtInfo.nState)
  179. return;
  180. // 保持处理
  181. if (m_HoldCallId == 0 && (EvtInfo.nState & HELD_STATE_MASK) == INNER_STATE_HELD)
  182. {
  183. m_HoldCallId = m_CallId;
  184. m_CallId = 0;
  185. m_HoldRecordFile = m_RecordFile;
  186. }
  187. // 接回处理
  188. if (m_HoldCallId != 0 && (EvtInfo.nState & HELD_STATE_MASK) != INNER_STATE_HELD)
  189. {
  190. m_CallId = m_HoldCallId;
  191. m_HoldCallId = 0;
  192. m_RecordFile = m_HoldRecordFile;
  193. }
  194. // 保存线路信息
  195. m_LineStatus = EvtInfo.nState;
  196. m_CallerNum = EvtInfo.szCallerNum;
  197. m_CalleeNum = EvtInfo.szCalleeNum;
  198. ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{LogicLineExt}: 线路状态, LineId = %lu,State=%d,CallId=%lu,Caller=%s,Callee=%s"), m_LineId, m_LineStatus, m_CallId, m_CallerNum, m_CalleeNum);
  199. // 统计线路状态变化
  200. _reportLineStatus();
  201. //获取内线呼入类型
  202. m_FinalExt = CStatisticsMgr::GetInstance().getFinalExt(m_CallId);
  203. // 发送线路状态变化信息到ACD(只有分机线路)
  204. pushLineData2ACD();
  205. // 通知会话状态变化,保持会话(m_nHoldCallId)不再通知
  206. CSessionHolder::GetInstance().onLineStatusUpdated(this);
  207. if (m_CallId == 0 && m_LineStatus== INNER_STATE_FREE) // 2022-01-06 设备外呼一个不存在的号码,callid为0,之前不会清除绑定的操作
  208. {
  209. resetLine();
  210. }
  211. }