中间件标准版5.1git,去除基础模块

IvrFlow.cpp 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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. {
  81. CPduEntity CmdCancelQuene(PDU_CMD_IVR_QUEUE_CANCEL); // ych 2018.7.3
  82. CmdCancelQuene.SetDataInt(1, PduEntity.GetDataInt(1));
  83. CmdCancelQuene.SetDataULong(2, PduEntity.GetDataULong(2));
  84. __procCancelQuene(CmdCancelQuene);
  85. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, "{procLineHangUp}: Ivr挂机前取消掉来电排队"); // ych 2018.5.31
  86. }
  87. case PDU_CMD_IVR_TURN_AGENT: // 转人工
  88. case PDU_CMD_IVR_PLAY_DTMF: // IVR通知放音收按键
  89. case PDU_CMD_IVR_CALL_OUT: // IVR自动外呼
  90. case PDU_CMD_IVR_TURN_OUTLINE: // IVR呼叫转移
  91. case PDU_CMD_IVR_FAX: // IVR通知收发传真
  92. case PDU_CMD_IVR_LEAVE_WORD: // IVR通知留言
  93. __transmitToTask(PduEntity);
  94. break;
  95. }
  96. }
  97. /*****************************************************************
  98. **【函数名称】 __TransmitToTask
  99. **【函数功能】 转发命令给Task
  100. **【参数】 PduEntity: 消息实体
  101. **【返回值】
  102. ***************************************************************/
  103. void CIvrFlow::__transmitToTask(CPduEntity &PduEntity)
  104. {
  105. // 设置IVR关联线路Id
  106. PduEntity.SetDataUInt(3, m_LineId == -1 ? 0 : m_LineId);
  107. CTaskMgr::GetInstance().onPduMessage(PduEntity);
  108. }
  109. /*****************************************************************
  110. **【函数名称】 __ProcCallInReturn
  111. **【函数功能】 CallIn命令返回
  112. **【参数】 PduEntity: 消息实体
  113. **【返回值】
  114. ***************************************************************/
  115. void CIvrFlow::__procCallInReturn(CPduEntity &PduEntity)
  116. {
  117. // 关联线路
  118. UINT LineId = PduEntity.GetDataUInt(5);
  119. CLogicLine *pLogicLine = CLineHolder::GetInstance().getLogicLine(LineId);
  120. if(pLogicLine == NULL) return;
  121. m_LineId = LineId;
  122. }
  123. /*****************************************************************
  124. **【函数名称】 __ProcTurnIvrReturn
  125. **【函数功能】 转IVR命令返回
  126. **【参数】 PduEntity: 消息实体
  127. **【返回值】
  128. ***************************************************************/
  129. void CIvrFlow::__procTurnIvrReturn(CPduEntity &PduEntity)
  130. {
  131. // 关联线路
  132. m_LineId = PduEntity.GetDataUInt(5);
  133. // 转Ivr结果通知Task,由Task返回给Ivr程序
  134. CTaskMgr::GetInstance().onTaskPduMsg(m_LineId, PduEntity);
  135. }
  136. /*****************************************************************
  137. **【函数名称】 __ProcWantAgentReturn
  138. **【函数功能】 请求排队命令
  139. **【参数】 PduEntity: 消息实体
  140. **【返回值】
  141. ***************************************************************/
  142. void CIvrFlow::__procWantAgent(CPduEntity &PduEntity)
  143. {
  144. if(PduEntity.GetIsExecReturn())
  145. {
  146. // 显示日志
  147. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL,_T("ACD->CTI, CMD = return[来电排队], \
  148. IVR = %d, IsSuccess = %u, Agent = %u, Ext = %u,Qcnt=%u"),
  149. PduEntity.GetDataInt(1),
  150. PduEntity.GetDataBool(0),
  151. PduEntity.GetDataUInt(9),
  152. PduEntity.GetDataUInt(10),
  153. PduEntity.GetDataUInt(11));
  154. // 请求排队的返回命令
  155. if(!PduEntity.GetDataBool(0))
  156. {
  157. // 请求排队失败,向ACD发送暂停排队命令
  158. CPduEntity CmdPauseQueue(PDU_CMD_CTI_ACD_QUEUE_PAUSE);
  159. CmdPauseQueue.SetDataInt(0, m_IvrFlowId);
  160. CNetworkCti::GetInstance().send2ACD(CmdPauseQueue);
  161. }
  162. else
  163. {
  164. // 排队成功设置排队标志为False
  165. m_IsQuene = false;
  166. }
  167. // 返回结果通知IVR
  168. CNetworkCti::GetInstance().send2IVR(PduEntity);
  169. }
  170. else
  171. {
  172. // 显示日志
  173. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("IVR->CTI, CMD = [来电排队], IVR = %d"), PduEntity.GetDataInt(1));
  174. // 设置排队标志为TRUE
  175. m_IsQuene = true;
  176. // 转发给ACD请求排队
  177. if(!CNetworkCti::GetInstance().send2ACD(PduEntity))
  178. {
  179. // 发送失败通知IVR结果
  180. PduEntity.SetToExecReturn();
  181. PduEntity.SetDataBool(0, false);
  182. CNetworkCti::GetInstance().send2IVR(PduEntity);
  183. }
  184. // 统计 REP_EVENT_WANT_AGENT
  185. CLogicLine* pHostLine = CLineHolder::GetInstance().getLogicLine(m_LineId);
  186. if(pHostLine == NULL) return;
  187. CStatisticsMgr::GetInstance().onCallDetail(pHostLine->callId(), REP_EVENT_WANT_AGENT, m_LineId, NULL);
  188. }
  189. }
  190. /*****************************************************************
  191. **【函数名称】 __ProcContinueQuene
  192. **【函数功能】 继续排队命令
  193. **【参数】 PduEntity: 消息实体
  194. **【返回值】
  195. ***************************************************************/
  196. void CIvrFlow::__procContinueQuene(CPduEntity &PduEntity)
  197. {
  198. if(PduEntity.GetIsExecReturn())
  199. {
  200. // 显示日志
  201. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL,_T("ACD->CTI, CMD = return[继续排队], \
  202. IVR = %d, IsSuccess = %d, Agent = %d, Ext = %d"),
  203. PduEntity.GetDataInt(1),
  204. PduEntity.GetDataBool(0),
  205. PduEntity.GetDataUInt(7),
  206. PduEntity.GetDataUInt(8));
  207. // ACD返回继续等待排队结果消息. 继续排队失败命令不处理
  208. if(!PduEntity.GetDataBool(0)) return;
  209. // 排队成功修改排队标志
  210. m_IsQuene = false;
  211. // 排队成功通知Task,由Task返回给Ivr程序
  212. CTaskMgr::GetInstance().onTaskPduMsg(m_LineId, PduEntity);
  213. }
  214. else
  215. {
  216. // 通知Task等待排队
  217. __transmitToTask(PduEntity);
  218. // 通知ACD继续排队
  219. if(!CNetworkCti::GetInstance().send2ACD(PduEntity))
  220. {
  221. // 发送失败通知IVR结果
  222. PduEntity.SetToExecReturn();
  223. PduEntity.SetDataBool(0, false);
  224. CNetworkCti::GetInstance().send2IVR(PduEntity);
  225. }
  226. }
  227. }
  228. /******************************************************************
  229. **【函数名称】 __ProcCancelQuene
  230. **【函数功能】 取消排队
  231. **【参数】 消息实体
  232. **【返回值】 void
  233. ****************************************************************/
  234. void CIvrFlow::__procCancelQuene(CPduEntity &PduEntity)
  235. {
  236. // 显示日志
  237. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("IVR->CTI, CMD = [取消排队], IVR = %d"), PduEntity.GetDataInt(1));
  238. // 是否正在排队
  239. if(!m_IsQuene) return;
  240. // 转发给ACD取消排队
  241. CNetworkCti::GetInstance().send2ACD(PduEntity);
  242. // 设置排队标志为False
  243. m_IsQuene = false;
  244. }