| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- #include "StdAfx.h"
- #include "LogicLineExt.h"
- #include "CallSession.h"
- #include "SessionHolder.h"
- #include "StatisticsMgr.h"
- #include "NetworkCti.h"
- #include "CtiCore.h"
- #include "TaskMgr.h"
- CLogicLineExt::CLogicLineExt(UINT ResId) : CLogicLine(ResId), m_AgentId(0), m_FinalExt(0), m_AssoLineType(0), m_HoldRecordFile(_T(""))
- {
- m_LineStatus = INNER_STATE_FREE;
- }
- CLogicLineExt::~CLogicLineExt(void)
- {
- }
- /*****************************************************************
- **【函数名称】 __telephoneNumBelongsTo
- **【函数功能】 获取归属地信息
- **【参数】 Number: 来电号码
- BelongsTo:输出参数,归属地
- **【返回值】
- ****************************************************************/
- void CLogicLineExt::__telephoneNumBelongsTo(const CString& Number, CString& BelongsTo)
- {
- // 去掉出局号码进行查询归属地
- // Number= Number.Right(Number.GetLength()-1); //屏蔽出局号,该行代码在测试环境中使用
- CString SqlFunc = _T("charindex"); // MS SQL SERVER 字符串匹配函数
- if (DB_MySQL == IOtlConnection::getInstance()->GetDatabaseType())
- SqlFunc = _T("locate"); // MYSQL 字符串匹配函数
- CString SQL;
- SQL.Format("select * from conf_phone where %s(rtrim(number),'%s') in (1,2)", SqlFunc, Number);
- IOtlRecordset* pRD = IOtlConnection::getInstance()->QueryRecords(SQL);
- if (NULL == pRD) //判断空值
- return;
- if (pRD->IsEOF())
- {
- IOtlRecordset::DestroyInstance(pRD); // 释放记录集
- return;
- }
- CString Province = _T("");
- CString City = _T("");
- CString Type = _T("");
- while (!pRD->IsEOF())
- {
- pRD->MoveNextRow();
- Province = pRD->GetValueStr(_T("Province"));
- City = pRD->GetValueStr(_T("City"));
- Type = pRD->GetValueStr(_T("Type"));
- }
- IOtlRecordset::DestroyInstance(pRD); // 释放记录集
- BelongsTo = Province.Trim() + _T("-") + City.Trim() + _T("-") + Type.Trim();
- }
- /*****************************************************************
- **【函数名称】 resetLine
- **【函数功能】 线路重置
- **【参数】
- **【返回值】
- ****************************************************************/
- void CLogicLineExt::resetLine()
- {
- // 清除线路信息
- m_FinalExt = 0;
- m_AssoLineType = 0;
- m_HoldRecordFile = "";
- CLogicLine::resetLine();
- }
- /*****************************************************************
- **【函数名称】 pushLineData2ACD
- **【函数功能】 将线路数据发送给ACD
- **【参数】
- **【返回值】
- ****************************************************************/
- void CLogicLineExt::pushLineData2ACD()
- {
- // 通过会话获取线路信息
- CString Data = _T("");
- CString TrunkNum = _T("");
- CCallSession* pSession = CSessionHolder::GetInstance().findSession(m_CallId);
- if (pSession != NULL)
- {
- // 获取随路数据
- Data = pSession->data();
- // 获取对端线路类型
- CLogicLine* pAssoLine = pSession->getAssoLine(this);
- if (pAssoLine != NULL)
- {
- TrunkNum = pAssoLine->calleeNum();
- m_AssoLineType = pAssoLine->type();
- //2018.5.19分机外线判定
- if (m_AssoLineType == DEV_RES_TYPE_VOIP)
- {
- m_AssoLineType = pAssoLine->typeExtTrunk();
- }
- // ych
- // 2019-9-12 bwj 满意度,分机挂机时不能挂断外线,故屏蔽掉
- if (m_LineStatus == INNER_STATE_FREE)
- {
- #ifdef ISNEEDMYD
- CPduEntity CmdTurnIvr(PDU_CMD_CTI_IVR_TURNIVR);
- CmdTurnIvr.SetDataULong(2, pAssoLine->callId()); // CallId
- CmdTurnIvr.SetDataString(3, pAssoLine->callerNum()); // 主叫
- CmdTurnIvr.SetDataString(4, pAssoLine->calleeNum()); // 被叫
- CmdTurnIvr.SetDataUInt(5, pAssoLine->lineId()); // 外线Id
- CmdTurnIvr.SetDataUInt(6, 0); // 分机Id
- CmdTurnIvr.SetDataUInt(7, 0); // IVr节点号
- CmdTurnIvr.SetDataString(8, "MYD"); // Ivr文件名
- CmdTurnIvr.SetDataString(9, ""); // 随路数据
- CmdTurnIvr.SetDataBool(10, false); // 是否返回
- BOOL bRet = CNetworkCti::GetInstance().send2IVR(CmdTurnIvr);
- // 发送IVR失败,转IVR失败,外线挂机
- if (!bRet)
- {
- LineOpParam pLineOpParam;
- memset(&pLineOpParam, 0, sizeof(pLineOpParam));
- CCtiCore::GetInstance().getDevLink().exec((long)this, LINE_OP_HANG_UP, pAssoLine->lineId(), &pLineOpParam);
- }
- #else
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Line}: 当前会话[%d]线路数:%d"), m_CallId, pSession->lineCount());
- //if (pSession->lineCount() == 2 && m_AssoLineType == DEV_RES_TYPE_TRUNK) // 对端线路是外线
- //{
- // CCtiCore::GetInstance().getDevLink().exec((long)-1, LINE_OP_HANG_UP, pAssoLine->lineId(), NULL);
- // ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Line}: 座席分机挂机,挂断关联中继线路"));
- //}
- #endif // ISNEEDMYD
- }
- }
- }
- // 发送线路状态变化信息到ACD
- CPduEntity Cmd(PDU_CMD_CTI_LINE_STATE);
- Cmd.SetDataUInt(0, m_LineId);
- Cmd.SetDataUInt(1, m_LineStatus);
- Cmd.SetDataULong(2, (m_CallId == 0 ? m_HoldCallId : m_CallId));
- Cmd.SetDataUInt(3, m_AgentId);
- Cmd.SetDataString(4, m_CallerNum);
- Cmd.SetDataString(5, m_CalleeNum);
- Cmd.SetDataString(6, Data);
- Cmd.SetDataUInt(7, m_AssoLineType);
- //if (m_LineStatus == INNER_STATE_ALERTING) //分机振铃事件才送归属地
- //{
- // CString NumberBelongsTo = _T("");
- // __telephoneNumBelongsTo(m_CallerNum, NumberBelongsTo);
- // ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("{Line}: 坐席线路来电振铃,来电归属地:%s"), NumberBelongsTo);
- // Cmd.SetDataString(8, NumberBelongsTo);
- //}
- Cmd.SetDataUInt(9, m_FinalExt);
- Cmd.SetDataUInt(10, m_CurrentOpType); // 传入当前线路操作类型
- Cmd.SetDataInt(11, m_ActionID);
- Cmd.SetDataUInt(12, m_IsMeeting); // 2020-01-05 坐席状态,标记是否再会议
- Cmd.SetDataString(13, TrunkNum); // 中继号
- CNetworkCti::GetInstance().send2ACD(Cmd);
- }
- /*****************************************************************
- **【函数名称】 pushRecord2ACD
- **【函数功能】 将录音数据发送给ACD
- **【参数】
- **【返回值】
- ****************************************************************/
- void CLogicLineExt::pushRecord2ACD()
- {
- // 向ACD发送录音文件名
- CPduEntity Pdu(PDU_CMD_CTI_RECORD);
- Pdu.SetDataUInt(0, m_LineId);
- Pdu.SetDataULong(1, m_CallId);
- Pdu.SetDataString(2, m_RecordFile);
- CNetworkCti::GetInstance().send2ACD(Pdu);
- // 显示日志
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("CTI->AGENT, PDU = [线路录音信息], Exten = %d, Agent = %d, RecordFile = %s"),
- m_LineId, m_AgentId, m_RecordFile);
- }
- /*****************************************************************
- **【函数名称】 onLineStatusUpdated
- **【函数功能】 处理线路状态变化
- **【参数】 EvtInfo: 线路资源状态
- **【返回值】
- ****************************************************************/
- void CLogicLineExt::onLineStatusUpdated(const EventResStatus &EvtInfo)
- {
- if (m_LineStatus == EvtInfo.nState)
- return;
- // 保持处理
- if (m_HoldCallId == 0 && (EvtInfo.nState & HELD_STATE_MASK) == INNER_STATE_HELD)
- {
- m_HoldCallId = m_CallId;
- m_CallId = 0;
- m_HoldRecordFile = m_RecordFile;
- }
- // 接回处理
- if (m_HoldCallId != 0 && (EvtInfo.nState & HELD_STATE_MASK) != INNER_STATE_HELD)
- {
- m_CallId = m_HoldCallId;
- m_HoldCallId = 0;
- m_RecordFile = m_HoldRecordFile;
- }
- // 保存线路信息
- m_LineStatus = EvtInfo.nState;
- m_CallerNum = EvtInfo.szCallerNum;
- m_CalleeNum = EvtInfo.szCalleeNum;
- 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);
- // 统计线路状态变化
- _reportLineStatus();
- //获取内线呼入类型
- m_FinalExt = CStatisticsMgr::GetInstance().getFinalExt(m_CallId);
- // 发送线路状态变化信息到ACD(只有分机线路)
- pushLineData2ACD();
- // 通知会话状态变化,保持会话(m_nHoldCallId)不再通知
- CSessionHolder::GetInstance().onLineStatusUpdated(this);
- if (m_CallId == 0 && m_LineStatus== INNER_STATE_FREE) // 2022-01-06 设备外呼一个不存在的号码,callid为0,之前不会清除绑定的操作
- {
- resetLine();
- }
- }
|