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

CellCallOut.cpp 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. #include "StdAfx.h"
  2. #include "CellCallOut.h"
  3. #include "NetworkIvr.h"
  4. #include "IvrFlow.h"
  5. #include "FlowDataProvider.h"
  6. IMPLEMENT_CELL_AUTOCREATE(CCellCallOut, CELL_NAME_CALL)
  7. CCellCallOut::CCellCallOut(void) : m_CalleeNumType(CELL_DATA_VAR), m_CallerNumType(CELL_DATA_VAR), m_Timeout(0), m_SuccessPos(0), m_FailPos(0), m_TimeCount(0)
  8. {
  9. }
  10. CCellCallOut::CCellCallOut( CCellCallOut & cellCallOut ) : CCellBase(cellCallOut)
  11. {
  12. m_CalleeNumType = cellCallOut.m_CalleeNumType;
  13. m_CallerNumType = cellCallOut.m_CallerNumType;
  14. m_Timeout = cellCallOut.m_Timeout;
  15. m_SuccessPos = cellCallOut.m_SuccessPos;
  16. m_FailPos = cellCallOut.m_FailPos;
  17. m_TimeCount = 0;
  18. m_CalleeNum = cellCallOut.m_CalleeNum;
  19. m_CallerNum = cellCallOut.m_CallerNum;
  20. CreateEx(0, AfxRegisterWndClass(CS_GLOBALCLASS), "", 0, 0, 0, 0, 0, 0, 0);
  21. }
  22. CCellCallOut::~CCellCallOut(void)
  23. {
  24. KillTimer(reinterpret_cast<long>(this));
  25. DestroyWindow();
  26. }
  27. BEGIN_MESSAGE_MAP(CCellCallOut, CWnd)
  28. ON_WM_TIMER()
  29. END_MESSAGE_MAP()
  30. /*****************************************************************
  31. **【函数名称】 operate
  32. **【函数功能】 节点执行函数
  33. **【参数】
  34. **【返回值】 下一个节点编号
  35. ****************************************************************/
  36. int CCellCallOut::operate( void )
  37. {
  38. if(m_pIvrFlow == NULL)
  39. return CELL_OP_ERROR;
  40. // 创建定时器
  41. if (m_Timeout > 0 )
  42. SetTimer(reinterpret_cast<long>(this), 1000, NULL);
  43. CString Info;
  44. _getCellInfo(Info);
  45. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}: 开始执行[%s]"), Info);
  46. // 获取被叫
  47. CString CalleeNum = "";
  48. if(m_CalleeNumType == CELL_DATA_VAR) // 目标号码类型为2时,存储的是变量名
  49. {
  50. if(!m_pIvrFlow->findVarValue(m_CalleeNum, CalleeNum))
  51. {
  52. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错, 被叫号码为空"), Info);
  53. KillTimer(reinterpret_cast<long>(this));
  54. return CELL_OP_ERROR;
  55. }
  56. }
  57. else
  58. {
  59. CalleeNum = m_CalleeNum;
  60. }
  61. // 获取主叫
  62. CString CallerNum = "";
  63. if(m_CallerNumType == CELL_DATA_VAR) // 目标号码类型为2时,存储的是变量名
  64. {
  65. if(!m_pIvrFlow->findVarValue(m_CallerNum, CallerNum))
  66. {
  67. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错, 主叫号码为空"), Info);
  68. KillTimer(reinterpret_cast<long>(this));
  69. return CELL_OP_ERROR;
  70. }
  71. }
  72. else
  73. {
  74. CallerNum = m_CallerNum;
  75. }
  76. m_pIvrFlow->addVar(SYSTEM_VAR_HUNT_GROUP, CalleeNum);
  77. CPduEntity cmdCallout(PDU_CMD_IVR_CALL_OUT);
  78. cmdCallout.SetDataInt(1, m_pIvrFlow->id());
  79. cmdCallout.SetDataString(4, CalleeNum);
  80. cmdCallout.SetDataString(5, CallerNum);
  81. cmdCallout.SetDataUInt(6, m_Timeout);
  82. if(!CNetworkIvr::GetInstance().send(cmdCallout))
  83. {
  84. KillTimer(reinterpret_cast<long>(this));
  85. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错, 向CTI发送消息失败"), Info);
  86. return CELL_OP_SEND_ERROR;
  87. }
  88. return CELL_OP_WAIT_FOR;
  89. }
  90. /*****************************************************************
  91. **【函数名称】 copy
  92. **【函数功能】 拷贝自身
  93. **【参数】
  94. **【返回值】 拷贝副本
  95. ****************************************************************/
  96. CCellBase * CCellCallOut::copy( void )
  97. {
  98. CCellBase * pCellBase = new CCellCallOut(*this);
  99. return pCellBase;
  100. }
  101. /*****************************************************************
  102. **【函数名称】 fillData
  103. **【函数功能】 节点解析,填充数据
  104. **【参数】 Provider:数据提供器
  105. **【返回值】 成功true,失败false
  106. ****************************************************************/
  107. bool CCellCallOut::fillData( IFlowDataProvider& Provider )
  108. {
  109. CString Data;
  110. do
  111. {
  112. if(!Provider.getData(CELL_ATTRIBUTE_POS, Data))
  113. {
  114. Data = _T("节点号");
  115. break;
  116. }
  117. else
  118. {
  119. sscanf_s(Data, _T("%d"), &m_Pos);
  120. if(m_Pos < 1)
  121. {
  122. Data = _T("节点号");
  123. break;
  124. }
  125. }
  126. if(!Provider.getData(CELL_ATTRIBUTE_CALLEE_NUM_TYPE, Data))
  127. {
  128. Data = _T("被叫号码类型");
  129. break;
  130. }
  131. else
  132. {
  133. sscanf_s(Data, _T("%d"), &m_CalleeNumType);
  134. if(m_CalleeNumType != CELL_DATA_VAL && m_CalleeNumType != CELL_DATA_VAR)
  135. {
  136. Data = _T("被叫号码类型");
  137. break;
  138. }
  139. }
  140. if(!Provider.getData(CELL_ATTRIBUTE_CALLEE_NUM, m_CalleeNum))
  141. {
  142. Data = _T("被叫号码");
  143. break;
  144. }
  145. if(!Provider.getData(CELL_ATTRIBUTE_CALLER_NUM_TYPE, Data))
  146. {
  147. Data = _T("主叫号码类型");
  148. break;
  149. }
  150. else
  151. {
  152. sscanf_s(Data, _T("%d"), &m_CalleeNumType);
  153. if(m_CalleeNumType != CELL_DATA_VAL && m_CalleeNumType != CELL_DATA_VAR)
  154. {
  155. Data = _T("主叫号码类型");
  156. break;
  157. }
  158. }
  159. if(!Provider.getData(CELL_ATTRIBUTE_CALLER_NUM, m_CalleeNum))
  160. {
  161. Data = _T("主叫号码");
  162. break;
  163. }
  164. if(!Provider.getData(CELL_ATTRIBUTE_TIMEOUT, Data))
  165. {
  166. Data = _T("呼叫超时");
  167. break;
  168. }
  169. else
  170. {
  171. sscanf_s(Data, _T("%d"), &m_Timeout);
  172. if(m_Timeout < 0)
  173. {
  174. Data = _T("呼叫超时");
  175. break;
  176. }
  177. }
  178. if(!Provider.getData(CELL_ATTRIBUTE_SUCCESS_POS, Data))
  179. {
  180. Data = _T("成功跳转节点");
  181. break;
  182. }
  183. else
  184. {
  185. sscanf_s(Data, _T("%d"), &m_SuccessPos);
  186. if(m_SuccessPos < 0)
  187. {
  188. Data = _T("成功跳转节点");
  189. break;
  190. }
  191. }
  192. if(!Provider.getData(CELL_ATTRIBUTE_FAIL_POS, Data))
  193. {
  194. Data = _T("失败跳转节点");
  195. break;
  196. }
  197. else
  198. {
  199. sscanf_s(Data, _T("%d"), &m_FailPos);
  200. if(m_FailPos < 0)
  201. {
  202. Data = _T("失败跳转节点");
  203. break;
  204. }
  205. }
  206. Provider.getData(CELL_ATTRIBUTE_NOTE, m_Note);
  207. return true;
  208. } while (false);
  209. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{Cell}: 节点[%s]解析失败, '%s'错误"), CELL_NAME_CALL, Data);
  210. return false;
  211. }
  212. /*****************************************************************
  213. **【函数名称】 onOpResultReturn
  214. **【函数功能】 处理PDU命令
  215. **【参数】 a_pPduEntity:PDU命令
  216. **【返回值】 下一个节点编号
  217. ****************************************************************/
  218. int CCellCallOut::onOpResultReturn( CPduEntity *a_pPduEntity )
  219. {
  220. KillTimer(reinterpret_cast<long>(this));
  221. CString Info;
  222. _getCellInfo(Info);
  223. if(a_pPduEntity->GetIsExecReturn() && a_pPduEntity->GetCmdType() == PDU_CMD_IVR_CALL_OUT)
  224. {
  225. if(a_pPduEntity->GetDataBool(0))
  226. {
  227. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}: 节点[%s]执行成功"), Info);
  228. return m_SuccessPos;
  229. }
  230. else
  231. {
  232. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}: 节点[%s]执行失败"), Info);
  233. return m_FailPos;
  234. }
  235. }
  236. // 挂机命令
  237. if(a_pPduEntity->GetCmdType() == PDU_CMD_CTI_IVR_HANGUP)
  238. {
  239. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}; 节点[%s]执行结束, 收到挂机消息"), Info);
  240. return m_FailPos;
  241. }
  242. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 节点[%s]执行异常, 收到异常PDU"), Info);
  243. return CELL_OP_ERROR;
  244. }
  245. /*****************************************************************
  246. **【函数名称】 OnTimer
  247. **【函数功能】 定时器响应函数
  248. **【参数】
  249. **【返回值】
  250. ****************************************************************/
  251. void CCellCallOut::OnTimer( UINT_PTR nIDEvent )
  252. {
  253. if(nIDEvent != reinterpret_cast<long>(this))
  254. return;
  255. if( m_TimeCount <= m_Timeout)
  256. {
  257. m_TimeCount++;
  258. }
  259. else
  260. {
  261. KillTimer(reinterpret_cast<long>(this));
  262. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 流程[%d]外呼节点[%d]呼叫超时, 执行挂机操作,"),
  263. (m_pIvrFlow != NULL) ? m_pIvrFlow->id() : 0, m_Pos);
  264. //执行挂机操作
  265. CPduEntity CmdHangUp(PDU_CMD_IVR_HANGUP);
  266. CmdHangUp.SetDataInt(1, m_pIvrFlow->id());
  267. CNetworkIvr::GetInstance().send(CmdHangUp);
  268. }
  269. CWnd::OnTimer(nIDEvent);
  270. }