中航光电的中间件仓库

LogicLineExt.cpp 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. CCallSession* pSession = CSessionHolder::GetInstance().findSession(m_CallId);
  78. if (pSession != NULL)
  79. {
  80. // 获取随路数据
  81. Data = pSession->data();
  82. // 获取对端线路类型
  83. CLogicLine* pAssoLine = pSession->getAssoLine(this);
  84. if (pAssoLine != NULL)
  85. {
  86. m_AssoLineType = pAssoLine->type();
  87. //2018.5.19分机外线判定
  88. if (m_AssoLineType == DEV_RES_TYPE_VOIP)
  89. {
  90. m_AssoLineType = pAssoLine->typeExtTrunk();
  91. }
  92. // ych
  93. // 2019-9-12 bwj 满意度,分机挂机时不能挂断外线,故屏蔽掉
  94. if (m_LineStatus == INNER_STATE_FREE)
  95. {
  96. #ifdef ISNEEDMYD
  97. CPduEntity CmdTurnIvr(PDU_CMD_CTI_IVR_TURNIVR);
  98. CmdTurnIvr.SetDataULong(2, pAssoLine->callId()); // CallId
  99. CmdTurnIvr.SetDataString(3, pAssoLine->callerNum()); // 主叫
  100. CmdTurnIvr.SetDataString(4, pAssoLine->calleeNum()); // 被叫
  101. CmdTurnIvr.SetDataUInt(5, pAssoLine->lineId()); // 外线Id
  102. CmdTurnIvr.SetDataUInt(6, 0); // 分机Id
  103. CmdTurnIvr.SetDataUInt(7, 0); // IVr节点号
  104. CmdTurnIvr.SetDataString(8, "MYD"); // Ivr文件名
  105. CmdTurnIvr.SetDataString(9, ""); // 随路数据
  106. CmdTurnIvr.SetDataBool(10, false); // 是否返回
  107. BOOL bRet = CNetworkCti::GetInstance().send2IVR(CmdTurnIvr);
  108. // 发送IVR失败,转IVR失败,外线挂机
  109. if (!bRet)
  110. {
  111. LineOpParam pLineOpParam;
  112. memset(&pLineOpParam, 0, sizeof(pLineOpParam));
  113. CCtiCore::GetInstance().getDevLink().exec((long)this, LINE_OP_HANG_UP, pAssoLine->lineId(), &pLineOpParam);
  114. }
  115. #else
  116. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Line}: 当前会话[%d]线路数:%d"), m_CallId, pSession->lineCount());
  117. //if (pSession->lineCount() == 2 && m_AssoLineType == DEV_RES_TYPE_TRUNK) // 对端线路是外线
  118. //{
  119. // CCtiCore::GetInstance().getDevLink().exec((long)-1, LINE_OP_HANG_UP, pAssoLine->lineId(), NULL);
  120. // ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Line}: 座席分机挂机,挂断关联中继线路"));
  121. //}
  122. #endif // ISNEEDMYD
  123. }
  124. }
  125. }
  126. // 发送线路状态变化信息到ACD
  127. CPduEntity Cmd(PDU_CMD_CTI_LINE_STATE);
  128. Cmd.SetDataUInt(0, m_LineId);
  129. Cmd.SetDataUInt(1, m_LineStatus);
  130. Cmd.SetDataULong(2, (m_CallId == 0 ? m_HoldCallId : m_CallId));
  131. Cmd.SetDataUInt(3, m_AgentId);
  132. Cmd.SetDataString(4, m_CallerNum);
  133. Cmd.SetDataString(5, m_CalleeNum);
  134. Cmd.SetDataString(6, Data);
  135. Cmd.SetDataUInt(7, m_AssoLineType);
  136. //if (m_LineStatus == INNER_STATE_ALERTING) //分机振铃事件才送归属地
  137. //{
  138. // CString NumberBelongsTo = _T("");
  139. // __telephoneNumBelongsTo(m_CallerNum, NumberBelongsTo);
  140. // ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("{Line}: 坐席线路来电振铃,来电归属地:%s"), NumberBelongsTo);
  141. // Cmd.SetDataString(8, NumberBelongsTo);
  142. //}
  143. Cmd.SetDataUInt(9, m_FinalExt);
  144. Cmd.SetDataUInt(10, m_CurrentOpType); // 传入当前线路操作类型
  145. Cmd.SetDataInt(11, m_ActionID);
  146. CNetworkCti::GetInstance().send2ACD(Cmd);
  147. }
  148. /*****************************************************************
  149. **【函数名称】 pushRecord2ACD
  150. **【函数功能】 将录音数据发送给ACD
  151. **【参数】
  152. **【返回值】
  153. ****************************************************************/
  154. void CLogicLineExt::pushRecord2ACD()
  155. {
  156. // 向ACD发送录音文件名
  157. CPduEntity Pdu(PDU_CMD_CTI_RECORD);
  158. Pdu.SetDataUInt(0, m_LineId);
  159. Pdu.SetDataULong(1, m_CallId);
  160. Pdu.SetDataString(2, m_RecordFile);
  161. CNetworkCti::GetInstance().send2ACD(Pdu);
  162. // 显示日志
  163. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("CTI->AGENT, PDU = [线路录音信息], Exten = %d, Agent = %d, RecordFile = %s"),
  164. m_LineId, m_AgentId, m_RecordFile);
  165. }
  166. /*****************************************************************
  167. **【函数名称】 onLineStatusUpdated
  168. **【函数功能】 处理线路状态变化
  169. **【参数】 EvtInfo: 线路资源状态
  170. **【返回值】
  171. ****************************************************************/
  172. void CLogicLineExt::onLineStatusUpdated(const EventResStatus &EvtInfo)
  173. {
  174. if (m_LineStatus == EvtInfo.nState)
  175. return;
  176. // 保持处理
  177. if (m_HoldCallId == 0 && (EvtInfo.nState & HELD_STATE_MASK) == INNER_STATE_HELD)
  178. {
  179. m_HoldCallId = m_CallId;
  180. m_CallId = 0;
  181. m_HoldRecordFile = m_RecordFile;
  182. }
  183. // 接回处理
  184. if (m_HoldCallId != 0 && (EvtInfo.nState & HELD_STATE_MASK) != INNER_STATE_HELD)
  185. {
  186. m_CallId = m_HoldCallId;
  187. m_HoldCallId = 0;
  188. m_RecordFile = m_HoldRecordFile;
  189. }
  190. // 保存线路信息
  191. m_LineStatus = EvtInfo.nState;
  192. m_CallerNum = EvtInfo.szCallerNum;
  193. m_CalleeNum = EvtInfo.szCalleeNum;
  194. 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);
  195. // 统计线路状态变化
  196. _reportLineStatus();
  197. //获取内线呼入类型
  198. m_FinalExt = CStatisticsMgr::GetInstance().getFinalExt(m_CallId);
  199. // 发送线路状态变化信息到ACD(只有分机线路)
  200. pushLineData2ACD();
  201. // 通知会话状态变化,保持会话(m_nHoldCallId)不再通知
  202. CSessionHolder::GetInstance().onLineStatusUpdated(this);
  203. }