hd

IvrFlow.cpp 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. #include "StdAfx.h"
  2. #include "IvrFlow.h"
  3. #include "LineHolder.h"
  4. #include "LogicLine.h"
  5. #include "NetworkCti.h"
  6. #include "TaskMgr.h"
  7. #include "StatisticsMgr.h"
  8. CIvrFlow::CIvrFlow(int FlowId) : m_IvrFlowId(FlowId), m_LineId(-1), m_IsQuene(false)
  9. {
  10. }
  11. CIvrFlow::~CIvrFlow(void)
  12. {
  13. }
  14. /*****************************************************************
  15. **【函数名称】 EndIvr
  16. **【函数功能】 IVR流程结束
  17. **【参数】
  18. **【返回值】
  19. ****************************************************************/
  20. void CIvrFlow::resetFlow()
  21. {
  22. m_IsQuene = false;
  23. m_LineId = -1;
  24. }
  25. /*****************************************************************
  26. **【函数名称】 ProcLineHangUp
  27. **【函数功能】 处理线路挂机
  28. **【参数】
  29. **【返回值】
  30. ****************************************************************/
  31. void CIvrFlow::procLineHangUp()
  32. {
  33. // 获取线路类对象指针
  34. CLogicLine *pLogicLine = CLineHolder::GetInstance().getLogicLine(m_LineId);
  35. if(pLogicLine == NULL) return;
  36. // 正在排队向ACD发送取消排队命令
  37. // 排队标志清除
  38. m_IsQuene = false;
  39. CPduEntity CmdCancelQuene(PDU_CMD_IVR_QUEUE_CANCEL);
  40. CmdCancelQuene.SetDataInt(1, m_IvrFlowId);
  41. CmdCancelQuene.SetDataULong(2, pLogicLine->callId());
  42. CNetworkCti::GetInstance().send2ACD(CmdCancelQuene);
  43. // 向IVR发送挂机命令
  44. CPduEntity CmdHangUp(PDU_CMD_CTI_IVR_HANGUP);
  45. CmdHangUp.SetDataInt(1, m_IvrFlowId);
  46. CmdHangUp.SetDataULong(2, pLogicLine->callId());
  47. CNetworkCti::GetInstance().send2IVR(CmdHangUp);
  48. // 流程重置
  49. resetFlow();
  50. }
  51. /*****************************************************************
  52. **【函数名称】 OnPduMessage
  53. **【函数功能】 Pdu命令处理接口
  54. **【参数】 PduEntity: 消息实体
  55. **【返回值】
  56. ***************************************************************/
  57. void CIvrFlow::onPduMessage(CPduEntity &PduEntity)
  58. {
  59. switch(PduEntity.GetCmdType())
  60. {
  61. case PDU_CMD_IVR_END: // 流程结束
  62. this->resetFlow();
  63. break;
  64. case PDU_CMD_CTI_IVR_CALLIN: // CallIn返回命令
  65. __procCallInReturn(PduEntity);
  66. break;
  67. case PDU_CMD_CTI_IVR_TURNIVR: // 转Ivr命令返回
  68. __procTurnIvrReturn(PduEntity);
  69. break;
  70. case PDU_CMD_IVR_WANT_AGENT: // 请求排队命令
  71. __procWantAgent(PduEntity);
  72. break;
  73. case PDU_CMD_IVR_QUEUE_CONTINUE: // 继续排队命令
  74. __procContinueQuene(PduEntity);
  75. break;
  76. case PDU_CMD_IVR_QUEUE_CANCEL: // 取消排队命令
  77. __procCancelQuene(PduEntity);
  78. break;
  79. case PDU_CMD_IVR_HANGUP: // Ivr挂机
  80. case PDU_CMD_IVR_TURN_AGENT: // 转人工
  81. case PDU_CMD_IVR_PLAY_DTMF: // IVR通知放音收按键
  82. case PDU_CMD_IVR_CALL_OUT: // IVR自动外呼
  83. case PDU_CMD_IVR_TURN_OUTLINE: // IVR呼叫转移
  84. case PDU_CMD_IVR_FAX: // IVR通知收发传真
  85. case PDU_CMD_IVR_LEAVE_WORD: // IVR通知留言
  86. __transmitToTask(PduEntity);
  87. break;
  88. }
  89. }
  90. /*****************************************************************
  91. **【函数名称】 __TransmitToTask
  92. **【函数功能】 转发命令给Task
  93. **【参数】 PduEntity: 消息实体
  94. **【返回值】
  95. ***************************************************************/
  96. void CIvrFlow::__transmitToTask(CPduEntity &PduEntity)
  97. {
  98. // 设置IVR关联线路Id
  99. PduEntity.SetDataUInt(3, m_LineId == -1 ? 0 : m_LineId);
  100. if (PduEntity.GetCmdType() == PDU_CMD_IVR_TURN_AGENT) {
  101. PduEntity.SetDataUInt(3, m_LineId);
  102. PduEntity.SetDataUInt(4, 0);
  103. PduEntity.SetDataString(5, m_Callee);
  104. }
  105. //2019.3.7
  106. __try {
  107. CTaskMgr::GetInstance().onPduMessage(PduEntity);
  108. }
  109. __except (EXCEPTION_EXECUTE_HANDLER)
  110. {
  111. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{CIvrFlow}:__transmitToTask,DoTask异常,CmdType=%d"), PduEntity.GetCmdType());
  112. }
  113. }
  114. /*****************************************************************
  115. **【函数名称】 __ProcCallInReturn
  116. **【函数功能】 CallIn命令返回
  117. **【参数】 PduEntity: 消息实体
  118. **【返回值】
  119. ***************************************************************/
  120. void CIvrFlow::__procCallInReturn(CPduEntity &PduEntity)
  121. {
  122. // 关联线路
  123. UINT LineId = PduEntity.GetDataUInt(5);
  124. CLogicLine *pLogicLine = CLineHolder::GetInstance().getLogicLine(LineId);
  125. if(pLogicLine == NULL) return;
  126. m_LineId = LineId;
  127. m_Caller = PduEntity.GetDataString(3);
  128. m_Callee = PduEntity.GetDataString(4);
  129. }
  130. /*****************************************************************
  131. **【函数名称】 __ProcTurnIvrReturn
  132. **【函数功能】 转IVR命令返回
  133. **【参数】 PduEntity: 消息实体
  134. **【返回值】
  135. ***************************************************************/
  136. void CIvrFlow::__procTurnIvrReturn(CPduEntity &PduEntity)
  137. {
  138. // 关联线路
  139. m_LineId = PduEntity.GetDataUInt(5);
  140. // 转Ivr结果通知Task,由Task返回给Ivr程序
  141. CTaskMgr::GetInstance().onTaskPduMsg(m_LineId, PduEntity);
  142. }
  143. /*****************************************************************
  144. **【函数名称】 __ProcWantAgentReturn
  145. **【函数功能】 请求排队命令
  146. **【参数】 PduEntity: 消息实体
  147. **【返回值】
  148. ***************************************************************/
  149. void CIvrFlow::__procWantAgent(CPduEntity &PduEntity)
  150. {
  151. if(PduEntity.GetIsExecReturn())
  152. {
  153. // 显示日志
  154. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL,_T("ACD->CTI, CMD = return[来电排队], \
  155. IVR = %d, IsSuccess = %u, Agent = %u, Ext = %u,Qcnt=%u"),
  156. PduEntity.GetDataInt(1),
  157. PduEntity.GetDataBool(0),
  158. PduEntity.GetDataUInt(9),
  159. PduEntity.GetDataUInt(10),
  160. PduEntity.GetDataUInt(11));
  161. // 请求排队的返回命令
  162. if(!PduEntity.GetDataBool(0))
  163. {
  164. // 请求排队失败,向ACD发送暂停排队命令
  165. CPduEntity CmdPauseQueue(PDU_CMD_CTI_ACD_QUEUE_PAUSE);
  166. CmdPauseQueue.SetDataInt(0, m_IvrFlowId);
  167. CNetworkCti::GetInstance().send2ACD(CmdPauseQueue);
  168. }
  169. else
  170. {
  171. // 排队成功设置排队标志为False
  172. m_IsQuene = false;
  173. }
  174. // 返回结果通知IVR
  175. CNetworkCti::GetInstance().send2IVR(PduEntity);
  176. }
  177. else
  178. {
  179. // 显示日志
  180. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("IVR->CTI, CMD = [来电排队], IVR = %d"), PduEntity.GetDataInt(1));
  181. // 设置排队标志为TRUE
  182. m_IsQuene = true;
  183. // 转发给ACD请求排队
  184. if(!CNetworkCti::GetInstance().send2ACD(PduEntity))
  185. {
  186. // 发送失败通知IVR结果
  187. PduEntity.SetToExecReturn();
  188. PduEntity.SetDataBool(0, false);
  189. CNetworkCti::GetInstance().send2IVR(PduEntity);
  190. }
  191. // 统计 REP_EVENT_WANT_AGENT
  192. CLogicLine* pHostLine = CLineHolder::GetInstance().getLogicLine(m_LineId);
  193. if(pHostLine == NULL) return;
  194. CStatisticsMgr::GetInstance().onCallDetail(pHostLine->callId(), REP_EVENT_WANT_AGENT, m_LineId, NULL);
  195. }
  196. }
  197. /*****************************************************************
  198. **【函数名称】 __ProcContinueQuene
  199. **【函数功能】 继续排队命令
  200. **【参数】 PduEntity: 消息实体
  201. **【返回值】
  202. ***************************************************************/
  203. void CIvrFlow::__procContinueQuene(CPduEntity &PduEntity)
  204. {
  205. if(PduEntity.GetIsExecReturn())
  206. {
  207. // 显示日志
  208. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL,_T("ACD->CTI, CMD = return[继续排队], \
  209. IVR = %d, IsSuccess = %d, Agent = %d, Ext = %d"),
  210. PduEntity.GetDataInt(1),
  211. PduEntity.GetDataBool(0),
  212. PduEntity.GetDataUInt(7),
  213. PduEntity.GetDataUInt(8));
  214. // ACD返回继续等待排队结果消息. 继续排队失败命令不处理
  215. if(!PduEntity.GetDataBool(0)) return;
  216. // 排队成功修改排队标志
  217. m_IsQuene = false;
  218. // 排队成功通知Task,由Task返回给Ivr程序
  219. CTaskMgr::GetInstance().onTaskPduMsg(m_LineId, PduEntity);
  220. }
  221. else
  222. {
  223. // 通知Task等待排队
  224. __transmitToTask(PduEntity);
  225. // 通知ACD继续排队
  226. if(!CNetworkCti::GetInstance().send2ACD(PduEntity))
  227. {
  228. // 发送失败通知IVR结果
  229. PduEntity.SetToExecReturn();
  230. PduEntity.SetDataBool(0, false);
  231. CNetworkCti::GetInstance().send2IVR(PduEntity);
  232. }
  233. }
  234. }
  235. /******************************************************************
  236. **【函数名称】 __ProcCancelQuene
  237. **【函数功能】 取消排队
  238. **【参数】 消息实体
  239. **【返回值】 void
  240. ****************************************************************/
  241. void CIvrFlow::__procCancelQuene(CPduEntity &PduEntity)
  242. {
  243. // 显示日志
  244. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("IVR->CTI, CMD = [取消排队], IVR = %d"), PduEntity.GetDataInt(1));
  245. // 是否正在排队
  246. if(!m_IsQuene) return;
  247. // 转发给ACD取消排队
  248. CNetworkCti::GetInstance().send2ACD(PduEntity);
  249. // 设置排队标志为False
  250. m_IsQuene = false;
  251. }