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

TaskMgr.cpp 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. #include "StdAfx.h"
  2. #include "TaskMgr.h"
  3. #include "TaskInc.h"
  4. #include "CtiCore.h"
  5. #include "MsgCenter.h"
  6. #include "LineHolder.h"
  7. #include "LogicLine.h"
  8. SINGLETON_IMPLEMENT(CTaskMgr)
  9. CTaskMgr::CTaskMgr(void)
  10. {
  11. }
  12. CTaskMgr::~CTaskMgr(void)
  13. {
  14. }
  15. /*****************************************************************
  16. **【函数名称】 __addTask
  17. **【函数功能】 添加Task
  18. **【参数】
  19. **【返回值】
  20. ****************************************************************/
  21. void CTaskMgr::__addTask( CTask* pTask )
  22. {
  23. m_TaskLock.Lock();
  24. m_TaskTable.SetAt(reinterpret_cast<LONG>(pTask), pTask);
  25. m_TaskLock.Unlock();
  26. }
  27. /*****************************************************************
  28. **【函数名称】 __onAgentLogin
  29. **【函数功能】 坐席签入处理
  30. **【参数】 消息实体
  31. **【返回值】
  32. ****************************************************************/
  33. void CTaskMgr::__onAgentLogin( CPduEntity &PduEntity )
  34. {
  35. // 显示日志
  36. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("Agent->CTI, CMD = [坐席签入], \
  37. Exten = %d, Agent = %d"),
  38. PduEntity.GetDataUInt(1),
  39. PduEntity.GetDataUInt(2));
  40. // 设置内线分机的当前坐席工号
  41. CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(PduEntity.GetDataUInt(1));
  42. if(pLine == NULL)
  43. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING, _T("{TaskMgr}: 坐席[%d]签入绑定分机失败: 无法获取目标分机[%d]"), PduEntity.GetDataUInt(2),
  44. PduEntity.GetDataUInt(1));
  45. else
  46. pLine->setAgentNum(PduEntity.GetDataUInt(2));
  47. }
  48. /*****************************************************************
  49. **【函数名称】 __onAgentLogout
  50. **【函数功能】 坐席签出处理
  51. **【参数】 消息实体
  52. **【返回值】
  53. ****************************************************************/
  54. void CTaskMgr::__onAgentLogout( CPduEntity &PduEntity )
  55. {
  56. // 显示日志
  57. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("Agent->CTI, CMD = [坐席签出], Exten = %d, Agent = %d"),
  58. PduEntity.GetDataUInt(1),
  59. PduEntity.GetDataUInt(2));
  60. // 设置内线分机的当前坐席工号
  61. CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(PduEntity.GetDataUInt(1));
  62. if(pLine != NULL)
  63. pLine->setAgentNum(0);
  64. }
  65. /*****************************************************************
  66. **【函数名称】 __onAgentReset
  67. **【函数功能】 重置处理
  68. **【参数】 消息实体
  69. **【返回值】
  70. ****************************************************************/
  71. void CTaskMgr::__onAgentReset( CPduEntity &PduEntity )
  72. {
  73. // 显示日志
  74. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("Agent->CTI, CMD = [坐席重置], Exten = %d"), PduEntity.GetDataUInt(1));
  75. // 获取线路类指针
  76. CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(PduEntity.GetDataUInt(1));
  77. if(pLine == NULL)
  78. return;
  79. // 删除关联任务
  80. removeTask(pLine->taskIdBinded());
  81. // 物理重置
  82. CCtiCore::GetInstance().getDevLink().exec(-1, LINE_OP_RESET, pLine->lineId(), NULL);
  83. }
  84. /*****************************************************************
  85. **【函数名称】 __onTaskFailed
  86. **【函数功能】 处理Task执行失败
  87. **【参数】 消息实体
  88. **【返回值】
  89. ****************************************************************/
  90. void CTaskMgr::__onTaskFailed( CTask* pTask, CPduEntity &PduEntity )
  91. {
  92. // 显示日志
  93. CString DevType;
  94. UINT HostLine;
  95. if(PduEntity.GetLocalDevType() == PDU_DEV_TYPE_ACD)
  96. {
  97. DevType = _T("ACD");
  98. HostLine = PduEntity.GetDataUInt(1);
  99. }
  100. else
  101. {
  102. DevType = _T("IVR");
  103. HostLine = PduEntity.GetDataUInt(3);
  104. }
  105. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING, _T("CTI->%s, CMD[%d]执行失败, Line = %d"), DevType, PduEntity.GetCmdType(), HostLine);
  106. // 命令返回
  107. PduEntity.SetToExecReturn();
  108. PduEntity.SetDataBool(0, false);
  109. CInterfaceWindow::getIocpCommInstance()->Send(&PduEntity, PduEntity.GetLocalDevType(), PduEntity.GetLocalDevId());
  110. // 移除Task
  111. removeTask(reinterpret_cast<LONG>(pTask));
  112. }
  113. /*****************************************************************
  114. **【函数名称】 __procDevOpProcess
  115. **【函数功能】 处理设备操作进展
  116. **【参数】 EvtType 消息事件类型
  117. lpContent 消息内容
  118. **【返回值】
  119. ****************************************************************/
  120. void CTaskMgr::__procDevOpProcess( UINT EvtType, const PARAM lpContent )
  121. {
  122. EventOpProcess &EvtInfo = *(EventOpProcess*)lpContent;
  123. // 查找到Task并处理
  124. CTask* pTask = findTask(EvtInfo.nInstance);
  125. if(pTask != NULL)
  126. pTask->OnDevOpProcess(EvtInfo);
  127. }
  128. /*****************************************************************
  129. **【函数名称】 __procDevOpResult
  130. **【函数功能】 设备操作结果返回
  131. **【参数】 EvtType 消息事件类型
  132. lpContent 消息内容
  133. **【返回值】
  134. ****************************************************************/
  135. void CTaskMgr::__procDevOpResult( UINT EvtType, const PARAM lpContent )
  136. {
  137. EventOpResult &EvtInfo = *(EventOpResult*)lpContent;
  138. // 查找到Task并处理
  139. CTask* pTask = findTask(EvtInfo.nInstance);
  140. if(pTask != NULL)
  141. {
  142. // 返回True代表处理完成,移除Task
  143. if(pTask->OnDevOpResult(EvtInfo))
  144. removeTask(EvtInfo.nInstance);
  145. }
  146. }
  147. /*****************************************************************
  148. **【函数名称】 __procDevOperator
  149. **【函数功能】 设备主动操作
  150. **【参数】 EvtType 消息事件类型
  151. lpContent 消息内容
  152. **【返回值】
  153. ****************************************************************/
  154. void CTaskMgr::__procDevOperator( UINT EvtType, const PARAM lpContent )
  155. {
  156. CTask *pTask = NULL;
  157. // 事件内容解析
  158. EventDevOperation &EvtInfo = *(EventDevOperation*)lpContent;
  159. switch(EvtInfo.nOpType)
  160. {
  161. case DEV_OP_CALL_IN: // 外线来电
  162. pTask = new CTaskDevCallIn(EvtInfo);
  163. break;
  164. case DEV_OP_CALL_OUT: // 物理外呼
  165. pTask = new CTaskDevCall(EvtInfo);
  166. break;
  167. default:
  168. break;
  169. }
  170. if(pTask == NULL)
  171. return;
  172. // 保存Task
  173. __addTask(pTask);
  174. // 返回Fals代表执行失败,移除Task
  175. if(!pTask->DoTask())
  176. removeTask((long)pTask);
  177. }
  178. /*****************************************************************
  179. **【函数名称】 init
  180. **【函数功能】 模块初始化
  181. **【参数】
  182. **【返回值】
  183. ****************************************************************/
  184. void CTaskMgr::init( void )
  185. {
  186. // 注册底层设备消息和设备操作结果
  187. CMsgCenter& MC = CMsgCenter::GetInstance();
  188. MC.regist(DEV_EVENT_DEV_OPERATOR, this);
  189. MC.regist(DEV_EVENT_LINE_OP_PROCESS, this);
  190. MC.regist(DEV_EVENT_LINE_OP_RESULT, this);
  191. }
  192. /*****************************************************************
  193. **【函数名称】 removeTask
  194. **【函数功能】 删除Task
  195. **【参数】
  196. **【返回值】
  197. ****************************************************************/
  198. void CTaskMgr::removeTask( long TaskId )
  199. {
  200. if(TaskId == TASK_ID_INVALID)
  201. return;
  202. m_TaskLock.Lock();
  203. CTask* pTask = NULL;
  204. if(m_TaskTable.Lookup(TaskId, pTask))
  205. {
  206. m_TaskTable.RemoveKey(TaskId);
  207. // 删除Task
  208. ASSERT(pTask != NULL);
  209. delete pTask;
  210. }
  211. m_TaskLock.Unlock();
  212. }
  213. /*****************************************************************
  214. **【函数名称】 findTask
  215. **【函数功能】 查找Task
  216. **【参数】
  217. **【返回值】
  218. ****************************************************************/
  219. CTask* CTaskMgr::findTask( long TaskId )
  220. {
  221. if(TaskId == TASK_ID_INVALID)
  222. return NULL;
  223. CTask* pTask = NULL;
  224. m_TaskLock.Lock();
  225. m_TaskTable.Lookup(TaskId, pTask);
  226. m_TaskLock.Unlock();
  227. return pTask;
  228. }
  229. /*****************************************************************
  230. **【函数名称】 onPduMessage
  231. **【函数功能】 Pdu命令处理接口
  232. **【参数】 PduEntity: 消息实体
  233. **【返回值】
  234. ***************************************************************/
  235. void CTaskMgr::onPduMessage( CPduEntity &PduEntity )
  236. {
  237. // 根据命令类型创建Task
  238. CTask *pTask = NULL;
  239. PDU_CMD_TYPE nCmdType = PduEntity.GetCmdType();
  240. switch(nCmdType)
  241. {
  242. case PDU_CMD_AGENT_LOGIN: // 坐席签入
  243. __onAgentLogin(PduEntity);
  244. break;
  245. case PDU_CMD_AGENT_LOGOUT: // 坐席签出
  246. __onAgentLogout(PduEntity);
  247. break;
  248. case PDU_CMD_AGENT_MAKECALL: // 坐席外呼
  249. pTask = new CTaskAgentCall(PduEntity);
  250. break;
  251. case PDU_CMD_AGENT_ANSWER: // 坐席应答
  252. pTask = new CTaskAgentAnswer(PduEntity);
  253. break;
  254. case PDU_CMD_AGENT_HANGUP: // 坐席挂机
  255. pTask = new CTaskAgentHungUp(PduEntity);
  256. break;
  257. case PDU_CMD_AGENT_CANCEL: // 坐席取消操作
  258. pTask = new CTaskAgentCancel(PduEntity);
  259. break;
  260. case PDU_CMD_AGENT_RESET: // 坐席重置
  261. __onAgentReset(PduEntity);
  262. break;
  263. case PDU_CMD_AGENT_HOLD: // 坐席保持
  264. pTask = new CTaskAgentHold(PduEntity);
  265. break;
  266. case PDU_CMD_AGENT_TAKEBACK: // 坐席接回
  267. pTask = new CTaskAgentTakeBack(PduEntity);
  268. break;
  269. case PDU_CMD_AGENT_TRANSTALK: // 坐席转移
  270. pTask = new CTaskAgentTransfer(PduEntity);
  271. break;
  272. case PDU_CMD_AGENT_THREETALK: // 坐席三方
  273. pTask = new CTaskAgentThreeTalk(PduEntity);
  274. break;
  275. case PDU_CMD_AGENT_CONSULTATION_CALL:// 协商呼叫
  276. pTask = new CTaskAgentConsulCall(PduEntity);
  277. break;
  278. case PDU_CMD_AGENT_CONFIRM_TRANSFER:// 确认转移
  279. onTaskPduMsg(PduEntity.GetDataUInt(1), PduEntity);
  280. break;
  281. case PDU_CMD_AGENT_MONI_LISTEN: // 监听
  282. pTask = new CTaskMonitorListen(PduEntity);
  283. break;
  284. case PDU_CMD_AGENT_MONI_REPLACE: // 代接
  285. pTask = new CTaskMonitorInstead(PduEntity);
  286. break;
  287. case PDU_CMD_AGENT_MONI_INSERT: // 强插
  288. pTask = new CTaskMonitorInsert(PduEntity);
  289. break;
  290. case PDU_CMD_AGENT_MONI_INTERCEPT: // 强截
  291. pTask = new CTaskMonitorGrab(PduEntity);
  292. break;
  293. case PDU_CMD_AGENT_MONI_CUT: // 强拆
  294. pTask = new CTaskMonitorCut(PduEntity);
  295. break;
  296. case PDU_CMD_AGENT_FAX: // 坐席传真
  297. pTask = new CTaskAgentFax(PduEntity);
  298. break;
  299. case PDU_CMD_AGENT_TURN_TO_IVR: // 坐席转IVR
  300. pTask = new CTaskAgentTurnIvr(PduEntity);
  301. break;
  302. case PDU_CMD_AGENT_MUTE: // 坐席静音
  303. pTask = new CTaskAgentMute(PduEntity);
  304. break;
  305. case PDU_CMD_IVR_HANGUP: // Ivr通知挂机
  306. pTask = new CTaskIvrHangUp(PduEntity);
  307. break;
  308. case PDU_CMD_IVR_TURN_AGENT: // IVR通知转坐席
  309. pTask = new CTaskIvrTurnAgent(PduEntity);
  310. break;
  311. case PDU_CMD_IVR_QUEUE_CONTINUE: // Ivr通知继续排队
  312. pTask = new CTaskIvrContinueQuene(PduEntity);
  313. break;
  314. case PDU_CMD_IVR_PLAY_DTMF: // IVR通知放音收按键
  315. pTask = new CTaskIvrPlayVoice(PduEntity);
  316. break;
  317. case PDU_CMD_IVR_CALL_OUT: // IVR呼叫
  318. pTask = new CTaskIvrCall(PduEntity);
  319. break;
  320. case PDU_CMD_IVR_TURN_OUTLINE: // IVR呼叫转移外线
  321. pTask = new CTaskIvrTurnOut(PduEntity);
  322. break;
  323. case PDU_CMD_IVR_FAX: // Ivr收发传真
  324. pTask = new CTaskIvrFax(PduEntity);
  325. break;
  326. case PDU_CMD_IVR_LEAVE_WORD: // Ivr留言
  327. pTask = new CTaskIvrLeaveWord(PduEntity);
  328. break;
  329. default:
  330. break;
  331. }
  332. if(pTask == NULL) return;
  333. // 保存Task
  334. __addTask(pTask);
  335. // 返回Fase代表操作失败,移除该Task
  336. if(!pTask->DoTask())
  337. __onTaskFailed(pTask, PduEntity);
  338. }
  339. /*****************************************************************
  340. **【函数名称】 onTaskPduMsg
  341. **【函数功能】 Task处理Pdu命令接口
  342. **【参数】 LineId: 线路ID
  343. PduEntity:消息实体
  344. **【返回值】
  345. ***************************************************************/
  346. void CTaskMgr::onTaskPduMsg( UINT LineId, CPduEntity &PduEntity )
  347. {
  348. CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(LineId);
  349. ASSERT(pLine != NULL);
  350. if(pLine == NULL)
  351. {
  352. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{TaskMgr}: Task处理PDU命令失败, 无法定位关联线路[%d]"), LineId);
  353. return;
  354. }
  355. CTask* pTask = findTask(pLine->taskIdBinded());
  356. if(pTask == NULL)
  357. {
  358. pLine->taskIdBinded() = TASK_ID_INVALID;
  359. if(PduEntity.GetCmdType() == PDU_CMD_AGENT_CONFIRM_TRANSFER)
  360. {
  361. // 返回命令
  362. PduEntity.SetToExecReturn();
  363. PduEntity.SetDataBool(0, false);
  364. CInterfaceWindow::getIocpCommInstance()->Send(&PduEntity, PduEntity.GetLocalDevType(), PduEntity.GetLocalDevId());
  365. }
  366. }
  367. else
  368. {
  369. // task处理Pdu命令返回成功,删除task
  370. if(pTask->OnCmdOperation(PduEntity))
  371. removeTask((long)pTask);
  372. }
  373. }
  374. /*****************************************************************
  375. **【函数名称】 onMessage
  376. **【函数功能】 消息事件处理函数
  377. **【参数】 EvtType 消息事件类型
  378. lpContent 消息内容
  379. **【返回值】
  380. ****************************************************************/
  381. void CTaskMgr::onMessage( UINT MsgType, const PARAM lpContent )
  382. {
  383. if(lpContent == NULL) return;
  384. switch(MsgType)
  385. {
  386. case DEV_EVENT_LINE_OP_PROCESS: // 设备操作进展
  387. __procDevOpProcess(MsgType, lpContent);
  388. break;
  389. case DEV_EVENT_LINE_OP_RESULT: // 设备操作结果
  390. __procDevOpResult(MsgType, lpContent);
  391. break;
  392. case DEV_EVENT_DEV_OPERATOR: // 设备主动操作
  393. __procDevOperator(MsgType, lpContent);
  394. break;
  395. }
  396. }