MiddleWares_YiHe 郑州颐和医院随访系统中间件

IvrCore.cpp 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. #include "StdAfx.h"
  2. #include "IvrCore.h"
  3. #include "FlowTemplate.h"
  4. #include "IvrFlow.h"
  5. #include "NetworkIvr.h"
  6. #include "Config.h"
  7. #include "../Public/Auth/AuthMgr.h"
  8. #include "../Public/DaemonClient/DaemonClient.h"
  9. SINGLETON_IMPLEMENT(CIvrCore)
  10. CIvrCore::CIvrCore(void)
  11. {
  12. }
  13. CIvrCore::~CIvrCore(void)
  14. {
  15. }
  16. /*****************************************************************
  17. **【函数名称】 __setupFlowEnvironment
  18. **【函数功能】 设置流程环境
  19. **【参数】
  20. **【返回值】 TRUE:解析成功,FALSE:解析失败
  21. ****************************************************************/
  22. bool CIvrCore::__setupFlowEnvironment( void )
  23. {
  24. bool Res = true;
  25. IOtlConnection* pDbControl = IOtlConnection::getInstance();
  26. IOtlRecordset *pRecordset = pDbControl->QueryRecords(_T("SELECT * FROM conf_ivr_flow"));
  27. if(NULL != pRecordset)
  28. {
  29. while(!pRecordset->IsEOF())
  30. {
  31. pRecordset->MoveNextRow();
  32. // 读取流程文件信息
  33. CString FileName = pRecordset->GetValueStr(_T("FilePath"));
  34. Res &= m_TemplateMgr.parseIvrFile(FileName);
  35. } // end while
  36. }
  37. m_FlowMgr.createFlow();
  38. IOtlRecordset::DestroyInstance(pRecordset);
  39. return Res;
  40. }
  41. /*****************************************************************
  42. **【函数名称】 __procMsgCtiCallIn
  43. **【函数功能】 处理CTI发过来的外线呼入消息
  44. **【参数】 pPduEntity:外线呼入消息
  45. **【返回值】
  46. ****************************************************************/
  47. void CIvrCore::__procMsgCtiCallIn( CPduEntity* pPduEntity )
  48. {
  49. pPduEntity->SetToExecReturn();
  50. CFlowTemplate *pTemplate = m_TemplateMgr.getTemplate(pPduEntity->GetDataUInt(5)); // 通过线路号查找关联流程模板
  51. if(pTemplate == NULL)
  52. pTemplate = m_TemplateMgr.getTemplate(pPduEntity->GetDataString(4)); // 根据被叫号码查找关联流程模板
  53. if(pTemplate != NULL)
  54. {
  55. CIvrFlow *pFlow = m_FlowMgr.getFreeFlow();
  56. if(pFlow != NULL)
  57. {
  58. pFlow->setFlowInfo(pPduEntity->GetDataULong(2), pPduEntity->GetDataUInt(5), pPduEntity->GetDataString(3), pPduEntity->GetDataString(4));
  59. pPduEntity->SetDataBool(0, TRUE);
  60. pPduEntity->SetDataInt(1, pFlow->id());
  61. CNetworkIvr::GetInstance().send(*pPduEntity);
  62. pFlow->start(pTemplate);
  63. return;
  64. }
  65. else
  66. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理外线来电时无空闲流程, Caller = %s"), pPduEntity->GetDataString(3));
  67. }
  68. else
  69. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理外线来电时找不到关联流程模板, Caller = %s"), pPduEntity->GetDataString(3));
  70. pPduEntity->SetDataBool(0, FALSE);
  71. CNetworkIvr::GetInstance().send(*pPduEntity);
  72. }
  73. /*****************************************************************
  74. **【函数名称】 __procMsgCtiPredictiveCall
  75. **【函数功能】 处理CTI发过来的预测外呼消息
  76. **【参数】 pPduEntity:外线呼入消息
  77. **【返回值】
  78. ****************************************************************/
  79. void CIvrCore::__procMsgCtiPredictiveCall( CPduEntity* pPduEntity )
  80. {
  81. pPduEntity->SetToExecReturn();
  82. CFlowTemplate *pTemplate = m_TemplateMgr.getPreCallTemplate();
  83. ASSERT(pTemplate != NULL);
  84. if(pTemplate != NULL)
  85. {
  86. CIvrFlow *pFlow = m_FlowMgr.getFreeFlow();
  87. if(pFlow != NULL)
  88. {
  89. pFlow->setFlowInfo(pPduEntity->GetDataULong(2), pPduEntity->GetDataUInt(5), pPduEntity->GetDataInt(6),
  90. pPduEntity->GetDataUInt(7), pPduEntity->GetDataString(3), pPduEntity->GetDataString(4));
  91. pPduEntity->SetDataBool(0, TRUE);
  92. pPduEntity->SetDataInt(1, pFlow->id());
  93. CNetworkIvr::GetInstance().send(*pPduEntity);
  94. pFlow->start(pTemplate);
  95. return;
  96. }
  97. else
  98. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理预测外呼时无空闲流程, Callee = %s"), pPduEntity->GetDataString(4));
  99. }
  100. else
  101. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理预测外呼时找不到关联流程模板, Callee = %s"), pPduEntity->GetDataString(4));
  102. pPduEntity->SetDataBool(0, FALSE);
  103. CNetworkIvr::GetInstance().send(*pPduEntity);
  104. }
  105. /*****************************************************************
  106. **【函数名称】 __procMsgCtiTurnIvr
  107. **【函数功能】 处理CTI发来的坐席转IVR消息
  108. **【参数】 pPduEntity:坐席转IVR命令
  109. **【返回值】
  110. ****************************************************************/
  111. void CIvrCore::__procMsgCtiTurnIvr( CPduEntity* pPduEntity )
  112. {
  113. pPduEntity->SetToExecReturn();
  114. CFlowTemplate* pTemplate = m_TemplateMgr.findTemplate(pPduEntity->GetDataString(8));
  115. if(pTemplate != NULL)
  116. {
  117. CIvrFlow *pFlow = m_FlowMgr.getFreeFlow();
  118. if(pFlow != NULL)
  119. {
  120. // 设置系统变量
  121. pFlow->setFlowInfo(pPduEntity->GetDataULong(2), pPduEntity->GetDataUInt(5), pPduEntity->GetDataString(3), pPduEntity->GetDataString(4));
  122. // 设置随路数据变量
  123. pFlow->setFlowAssoData(pPduEntity->GetDataString(9));
  124. pPduEntity->SetDataBool(0, TRUE);
  125. pPduEntity->SetDataInt(1, pFlow->id());
  126. CNetworkIvr::GetInstance().send(*pPduEntity);
  127. pFlow->start(pTemplate);
  128. return;
  129. }
  130. else
  131. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理跳转IVR时无空闲流程"));
  132. }
  133. else
  134. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理跳转IVR时找不到目标流程模板"));
  135. pPduEntity->SetDataBool(0,FALSE);
  136. CNetworkIvr::GetInstance().send(*pPduEntity);
  137. }
  138. /*****************************************************************
  139. **【函数名称】 __procMsgCtiHangup
  140. **【函数功能】 处理CTI发来的外线挂机消息
  141. **【参数】 pPduEntity:Pdu命令
  142. **【返回值】
  143. ****************************************************************/
  144. void CIvrCore::__procMsgCtiHangup( CPduEntity* pPduEntity )
  145. {
  146. int FlowId = pPduEntity->GetDataInt(1);
  147. CIvrFlow *pFlow = m_FlowMgr.getFlow(FlowId);
  148. if(pFlow != NULL && pFlow->state() == IVR_FLOW_STATE_RUN)
  149. pFlow->procPdu(pPduEntity);
  150. else
  151. ILogger::getInstance().log(LOG_CLASS_SOCKET,LOG_LEVEL_WARNING,_T("{Core}: 收到外线挂机消息, 但关联流程线路[%d]已释放"), FlowId);
  152. }
  153. /*****************************************************************
  154. **【函数名称】 stage1Start
  155. **【函数功能】 第一阶段启动
  156. **【参数】
  157. **【返回值】
  158. ****************************************************************/
  159. bool CIvrCore::stage1Start( void )
  160. {
  161. // 连接配置数据库
  162. if(!IOtlConnection::getInstance()->Connect())
  163. {
  164. AfxMessageBox(STR_ERR_CORE_INIT_DB);
  165. return false;
  166. }
  167. // 加载配置
  168. if(!CConfig::load())
  169. {
  170. IOtlConnection::getInstance()->Disconnect();
  171. AfxMessageBox(STR_ERR_CORE_INIT_CFG);
  172. return false;
  173. }
  174. return true;
  175. }
  176. /*****************************************************************
  177. **【函数名称】 stage2Start
  178. **【函数功能】 第一阶段启动
  179. **【参数】 ErrInfo: 出错信息
  180. **【返回值】
  181. ****************************************************************/
  182. bool CIvrCore::stage2Start( void )
  183. {
  184. // 建立网络通讯
  185. if(!CNetworkIvr::GetInstance().init())
  186. {
  187. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("%s"), STR_ERR_CORE_INIT_NETWORK);
  188. return false;
  189. }
  190. // #ifndef _DEBUG
  191. // CAuthMgr::GetInstance().init();
  192. // #endif
  193. if(!__setupFlowEnvironment())
  194. {
  195. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("%s"), STR_ERR_CORE_INIT_FLOW);
  196. return false;
  197. }
  198. // 启动自动流程
  199. m_TemplateMgr.execAutoFlowTemplate(m_FlowMgr);
  200. CDaemonClient::GetInstance().doWork();
  201. return true;
  202. }
  203. /*****************************************************************
  204. **【函数名称】 exit
  205. **【函数功能】 退出IVR
  206. **【参数】
  207. **【返回值】
  208. ****************************************************************/
  209. void CIvrCore::exit( void )
  210. {
  211. CNetworkIvr::GetInstance().release();
  212. IOtlConnection::getInstance()->Disconnect();
  213. }
  214. /*****************************************************************
  215. **【函数名称】 procPdu
  216. **【函数功能】 处理CTI发过来的PDU消息
  217. **【参数】 a_pPduEntity:PDU消息
  218. **【返回值】
  219. ****************************************************************/
  220. void CIvrCore::procPdu( CPduEntity* pPduEntity )
  221. {
  222. // 返回命令的处理
  223. if(pPduEntity->GetIsExecReturn())
  224. {
  225. if(pPduEntity->GetCmdType() == PDU_CMD_IVR_HANGUP)
  226. return;
  227. CIvrFlow *pFlow = m_FlowMgr.getFlow(pPduEntity->GetDataInt(1));
  228. if(pFlow != NULL)
  229. {
  230. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("CTI -> IVR, CMD = Return[%d], IVR = %d, 执行结果 = %d"),
  231. pPduEntity->GetCmdType(),
  232. pPduEntity->GetDataInt(1),
  233. pPduEntity->GetDataBool(0));
  234. pFlow->procPdu(pPduEntity);
  235. }
  236. else
  237. {
  238. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING,_T("CTI -> IVR, CMD = Return[%d], IVR = %d, 执行结果 = %d, IVR线路已释放"),
  239. pPduEntity->GetCmdType(),
  240. pPduEntity->GetDataInt(1),
  241. pPduEntity->GetDataBool(0));
  242. }
  243. }
  244. else
  245. {
  246. switch(pPduEntity->GetCmdType())
  247. {
  248. case PDU_CMD_CTI_IVR_CALLIN: // CTI通知IVR外线来电
  249. __procMsgCtiCallIn(pPduEntity);
  250. break;
  251. case PDU_CMD_CTI_IVR_PREDICTIVECALL: // CTI通知IVR预测外呼
  252. __procMsgCtiPredictiveCall(pPduEntity);
  253. break;
  254. case PDU_CMD_CTI_IVR_TURNIVR: // CTI通知IVR转IVR
  255. __procMsgCtiTurnIvr(pPduEntity);
  256. break;
  257. case PDU_CMD_CTI_IVR_HANGUP: // CTI通知IVR外线挂机
  258. __procMsgCtiHangup(pPduEntity);
  259. break;
  260. default:
  261. break;
  262. } // end switch
  263. }
  264. }
  265. /*****************************************************************
  266. **【函数名称】 onNetLinkUpdated
  267. **【函数功能】 响应网络连接成功或断开事件
  268. **【参数】 IsConnect:网络连接成功或断开
  269. **【返回值】
  270. ****************************************************************/
  271. void CIvrCore::onNetLinkUpdated( bool IsConnect )
  272. {
  273. m_FlowMgr.onNetLinkUpdated(IsConnect);
  274. }