升龙物业 老版本 ocx IPO, 加密狗 转值班电话

IvrFlow.cpp 7.5KB

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