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

Agent.cpp 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. #include "StdAfx.h"
  2. #include "Agent.h"
  3. #include "Config.h"
  4. #include "SLogic.h"
  5. #include "AcdCore.h"
  6. #include "MsgCenter.h"
  7. #include "NetworkAcd.h"
  8. CAgent::CAgent(UINT a_AgentID, UINT a_ExtID, LPCTSTR a_GroupID, UINT a_AgentType, UINT a_PostProcessingTime)
  9. {
  10. // 网络属性
  11. CNetworkAcd::GetInstance().getAgentLinkInfo(a_AgentID, m_AgentIp, m_AgentPort);
  12. // 基本属性
  13. m_AgentID = a_AgentID;
  14. m_Exten = a_ExtID;
  15. m_GroupID = a_GroupID;
  16. m_AgentType = (AGENT_TYPE)a_AgentType;
  17. m_State = AGENT_STATE_UNKNOWN;
  18. m_AssoExtState = INNER_STATE_FREE;
  19. m_IsRepose = false;
  20. // 业务属性
  21. m_AnswerCount = 0;
  22. m_ReposeCount = 0;
  23. m_TimeFree = 0;
  24. m_TimeRepos = 0;
  25. m_TimeTalk = 0;
  26. m_TimePostProcessing = (a_PostProcessingTime == 0) ? CConfig::postProcessingTime() : a_PostProcessingTime;
  27. // 定时器初始化
  28. m_PollTimer.SetTimedEvent(this, &CAgent::__onTimerPoll);
  29. m_PollTimer.Start(1000);
  30. // 通知统计模块座席签入
  31. __reportLogin();
  32. // 添加消息可供视图刷新
  33. CMsgCenter::GetInstance().pushMsg(ACD_MSG_AGENT_STATE_UPDAET, (const PARAM)m_AgentID);
  34. }
  35. CAgent::~CAgent(void)
  36. {
  37. m_PollTimer.StopSafely();
  38. m_AgentTimer.StopSafely();
  39. }
  40. /*****************************************************************
  41. **【函数名称】 __reportLogin
  42. **【函数功能】 签出统计通知
  43. **【参数】
  44. **【返回值】
  45. ****************************************************************/
  46. void CAgent::__reportLogin()
  47. {
  48. // 通知统计模块 REP_EVENT_LOGIN
  49. T_EvtLogIn repLogin = { 0 };
  50. repLogin.nAgentID = m_AgentID;
  51. repLogin.nExtID = m_Exten;
  52. repLogin.nAgentType = m_AgentType;
  53. lstrcpy(repLogin.szGroup, m_GroupID);
  54. lstrcpy(repLogin.szAgentIP, m_AgentIp);
  55. CSLogic::GetInstance().onSEvent(m_AgentID, REP_EVENT_LOGIN, &repLogin);
  56. }
  57. /*****************************************************************
  58. **【函数名称】 __reportLogout
  59. **【函数功能】 签出统计通知
  60. **【参数】 HostAgent: 签出当前座席的主控座席
  61. **【返回值】
  62. ****************************************************************/
  63. void CAgent::__reportLogout( const UINT HostAgent )
  64. {
  65. if(m_State == AGENT_STATE_REPOSE )
  66. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  67. if( m_State == AGENT_STATE_POST_PROCESSING )
  68. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  69. // 通知统计模块 REP_EVENT_LOGOUT
  70. T_EvtLogout repLogout = { 0 };
  71. repLogout.nLogoutHost = HostAgent;
  72. repLogout.nTimeFree = m_TimeFree;
  73. repLogout.nTimeRepose = m_TimeRepos;
  74. repLogout.nTimeTalk = m_TimeTalk;
  75. repLogout.nAnswerCount = m_AnswerCount;
  76. repLogout.nReposeCount = m_ReposeCount;
  77. CSLogic::GetInstance().onSEvent(m_AgentID, REP_EVENT_LOGOUT, &repLogout);
  78. }
  79. /*****************************************************************
  80. **【函数名称】 __onStatusUpdate
  81. **【函数功能】 座席状态变更通知
  82. **【参数】
  83. **【返回值】
  84. ****************************************************************/
  85. void CAgent::__onStatusUpdate( AGENT_STATE State, bool StartFlag )
  86. {
  87. T_EvtStatus EvtStatus;
  88. EvtStatus.State = State;
  89. EvtStatus.StartFlag = StartFlag;
  90. CSLogic::GetInstance().onSEvent(m_AgentID, REP_EVENT_STATE, &EvtStatus);
  91. }
  92. /*****************************************************************
  93. **【函数名称】 __reportStatus
  94. **【函数功能】 通知各方座席当前状态
  95. **【参数】
  96. **【返回值】
  97. ****************************************************************/
  98. void CAgent::__reportStatus( void )
  99. {
  100. // 通知OCX座席当前状态
  101. CPduEntity Cmd(PDU_CMD_ACD_AGENT_STATE);
  102. Cmd.SetDataUInt(0, m_Exten);
  103. Cmd.SetDataUInt(1, m_AgentID);
  104. Cmd.SetDataUInt(2, m_State);
  105. CNetworkAcd::GetInstance().send2Agent(m_AgentID, &Cmd);
  106. // 添加消息可供视图刷新
  107. CMsgCenter::GetInstance().pushMsg(ACD_MSG_AGENT_STATE_UPDAET, (PARAM)m_AgentID);
  108. }
  109. /*****************************************************************
  110. **【函数名称】 __onTimerPoll
  111. **【函数功能】 轮询定时器处理
  112. **【参数】
  113. **【返回值】
  114. ****************************************************************/
  115. void CAgent::__onTimerPoll( void )
  116. {
  117. if(m_State == AGENT_STATE_FREE)
  118. m_TimeFree++;
  119. else if(m_State == AGENT_STATE_BUSY)
  120. m_TimeTalk++;
  121. if(m_IsRepose)
  122. m_TimeRepos++;
  123. }
  124. /*****************************************************************
  125. **【函数名称】 __onTimerPostProcessing
  126. **【函数功能】 话后处理时长定时器处理
  127. **【参数】
  128. **【返回值】
  129. ****************************************************************/
  130. void CAgent::__onTimerPostProcessing( void )
  131. {
  132. if(m_State == AGENT_STATE_POST_PROCESSING)
  133. {
  134. setState(AGENT_STATE_FREE);
  135. }
  136. }
  137. /*****************************************************************
  138. **【函数名称】 __onTimerLock
  139. **【函数功能】 座席被锁定超时处理
  140. **【参数】
  141. **【返回值】
  142. ****************************************************************/
  143. void CAgent::__onTimerLock( void )
  144. {
  145. if(m_State == AGENT_STATE_REQUESTED)
  146. {
  147. setState(AGENT_STATE_FREE, true);
  148. }
  149. }
  150. /*****************************************************************
  151. **【函数名称】 __setTimer
  152. **【函数功能】 设立定时器
  153. **【参数】
  154. **【返回值
  155. ****************************************************************/
  156. void CAgent::__setTimer( UINT TimmerId, UINT Elapse )
  157. {
  158. if(TimmerId == TIMER_POST_PROCESSING)
  159. {
  160. m_AgentTimer.StopSafely();
  161. m_AgentTimer.SetTimedEvent(this, &CAgent::__onTimerPostProcessing);
  162. m_AgentTimer.Start(Elapse, false, true, WT_EXECUTEDEFAULT);
  163. }
  164. else if(TimmerId == TIMER_LOCK_PERIOD)
  165. {
  166. m_AgentTimer.StopSafely();
  167. m_AgentTimer.SetTimedEvent(this, &CAgent::__onTimerLock);
  168. m_AgentTimer.Start(Elapse, false, true, WT_EXECUTEDEFAULT);
  169. }
  170. else
  171. {
  172. ASSERT(FALSE);
  173. }
  174. }
  175. /*****************************************************************
  176. **【函数名称】 __killTimer
  177. **【函数功能】 删除定时器
  178. **【参数】
  179. **【返回值
  180. ****************************************************************/
  181. void CAgent::__killTimer( UINT TimmerId )
  182. {
  183. m_AgentTimer.Stop();
  184. }
  185. /*****************************************************************
  186. **【函数名称】 release
  187. **【函数功能】 清理资源
  188. **【参数】 HostAgent: 主控制坐席工号
  189. **【返回值】
  190. ****************************************************************/
  191. void CAgent::release( UINT HostAgent )
  192. {
  193. m_PollTimer.StopSafely();
  194. m_AgentTimer.StopSafely();
  195. // 设置状态为注销
  196. setState(AGENT_STATE_LOGOUT);
  197. // 通知统计模块 REP_EVENT_LOGOUT
  198. __reportLogout(HostAgent);
  199. // 关闭Agent端SOCKET连接
  200. CNetworkAcd::GetInstance().shutDownAgentLink(m_AgentID);
  201. // 添加消息可供视图刷新
  202. CMsgCenter::GetInstance().pushMsg(ACD_MSG_AGENT_LOGOUT, (const PARAM)m_AgentID);
  203. }
  204. /*****************************************************************
  205. **【函数名称】 setState
  206. **【函数功能】 设置座席状态
  207. **【参数】 a_AgentState:座席当前逻辑状态
  208. **【返回值】
  209. ****************************************************************/
  210. BOOL CAgent::setState( AGENT_STATE a_AgentState, bool IsForce/* = false*/ )
  211. {
  212. CSingleLock Locker(&m_Cs4Lock, TRUE);
  213. switch(a_AgentState)
  214. {
  215. case AGENT_STATE_BUSY: // 通话
  216. {
  217. switch(m_State)
  218. {
  219. case AGENT_STATE_BUSY:
  220. return TRUE;
  221. break;
  222. case AGENT_STATE_REQUESTED:
  223. __killTimer(TIMER_LOCK_PERIOD);
  224. break;
  225. case AGENT_STATE_POST_PROCESSING:
  226. {
  227. __killTimer(TIMER_POST_PROCESSING);
  228. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  229. }
  230. break;
  231. case AGENT_STATE_REPOSE:
  232. {
  233. m_IsRepose = false;
  234. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  235. }
  236. break;
  237. case AGENT_STATE_LOGOUT:
  238. return FALSE;
  239. break;
  240. }
  241. __onStatusUpdate(AGENT_STATE_BUSY, true);
  242. m_State = AGENT_STATE_BUSY;
  243. }
  244. break;
  245. case AGENT_STATE_REPOSE: // 小休
  246. {
  247. switch(m_State)
  248. {
  249. case AGENT_STATE_REPOSE:
  250. return TRUE;
  251. break;
  252. case AGENT_STATE_POST_PROCESSING:
  253. {
  254. __killTimer(TIMER_POST_PROCESSING);
  255. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  256. }
  257. break;
  258. case AGENT_STATE_BUSY:
  259. case AGENT_STATE_LOGOUT:
  260. case AGENT_STATE_REQUESTED:
  261. return FALSE;
  262. break;
  263. }
  264. m_ReposeCount++;
  265. m_IsRepose = true;
  266. m_State = AGENT_STATE_REPOSE;
  267. // 统计小休开始
  268. __onStatusUpdate(AGENT_STATE_REPOSE, true);
  269. }
  270. break;
  271. case AGENT_STATE_POST_PROCESSING: // 话后处理
  272. {
  273. switch(m_State)
  274. {
  275. case AGENT_STATE_POST_PROCESSING:
  276. return TRUE;
  277. break;
  278. case AGENT_STATE_BUSY:
  279. __onStatusUpdate(AGENT_STATE_BUSY, false);
  280. break;
  281. case AGENT_STATE_FREE:
  282. case AGENT_STATE_REPOSE:
  283. case AGENT_STATE_REQUESTED:
  284. case AGENT_STATE_LOGOUT:
  285. return FALSE;
  286. break;
  287. }
  288. // 统计话后处理开始
  289. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, true);
  290. m_State = AGENT_STATE_POST_PROCESSING;
  291. if (m_TimePostProcessing > 0)
  292. __setTimer(TIMER_POST_PROCESSING, m_TimePostProcessing * 1000); // 启动话后处理定时器
  293. }
  294. break;
  295. case AGENT_STATE_FREE: // 空闲
  296. {
  297. switch(m_State)
  298. {
  299. case AGENT_STATE_FREE:
  300. return TRUE;
  301. break;
  302. case AGENT_STATE_BUSY:
  303. {
  304. if(IsForce)
  305. __onStatusUpdate(AGENT_STATE_BUSY, false);
  306. else
  307. return FALSE;
  308. }
  309. break;
  310. case AGENT_STATE_POST_PROCESSING:
  311. {
  312. __killTimer(TIMER_POST_PROCESSING);
  313. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  314. }
  315. break;
  316. case AGENT_STATE_REPOSE:
  317. {
  318. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  319. m_IsRepose = false;
  320. }
  321. break;
  322. case AGENT_STATE_REQUESTED:
  323. {
  324. if(IsForce)
  325. __killTimer(TIMER_LOCK_PERIOD);
  326. else
  327. return FALSE;
  328. }
  329. break;
  330. case AGENT_STATE_LOGOUT:
  331. return FALSE;
  332. break;
  333. }
  334. m_State = m_IsRepose ? AGENT_STATE_REPOSE : AGENT_STATE_FREE;
  335. }
  336. break;
  337. case AGENT_STATE_REQUESTED: // 被请求
  338. {
  339. ASSERT(m_State == AGENT_STATE_FREE);
  340. switch(m_State)
  341. {
  342. case AGENT_STATE_REQUESTED:
  343. case AGENT_STATE_BUSY:
  344. case AGENT_STATE_REPOSE:
  345. case AGENT_STATE_POST_PROCESSING:
  346. case AGENT_STATE_LOGOUT:
  347. return FALSE;
  348. break;
  349. }
  350. __setTimer(TIMER_LOCK_PERIOD, CConfig::agentLockedPeriod() * 1000); // 被请求超时处理定时器
  351. m_State = AGENT_STATE_REQUESTED;
  352. }
  353. break;
  354. default:
  355. {
  356. switch(m_State)
  357. {
  358. case AGENT_STATE_BUSY:
  359. __onStatusUpdate(AGENT_STATE_BUSY, false);
  360. break;
  361. case AGENT_STATE_POST_PROCESSING:
  362. {
  363. __killTimer(TIMER_POST_PROCESSING);
  364. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  365. }
  366. break;
  367. case AGENT_STATE_REPOSE:
  368. {
  369. m_IsRepose = false;
  370. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  371. }
  372. break;
  373. case AGENT_STATE_REQUESTED:
  374. __killTimer(TIMER_LOCK_PERIOD);
  375. break;
  376. }
  377. m_State = a_AgentState;
  378. }
  379. break;
  380. } // end switch
  381. // 通知座席当前状态变化
  382. __reportStatus();
  383. return TRUE;
  384. }
  385. /*****************************************************************
  386. **【函数名称】 onAssoExtStatusUpdated
  387. **【函数功能】 关联分机状态更新的处理函数
  388. **【参数】 a_ExtState:分机当前状态
  389. Param:附加参数
  390. **【返回值】
  391. ****************************************************************/
  392. void CAgent::onAssoExtStatusUpdated( INNER_STATE a_ExtState, PARAM Param /*= NULL*/ )
  393. {
  394. CPduEntity * pCmd = (CPduEntity *)Param;
  395. m_AssoExtState = a_ExtState;
  396. switch(a_ExtState)
  397. {
  398. case INNER_STATE_ALERTING:
  399. {
  400. // 来电振铃时解除请求锁定等状态
  401. if(m_State == AGENT_STATE_POST_PROCESSING || m_State == AGENT_STATE_REPOSE || m_State == AGENT_STATE_REQUESTED)
  402. setState(AGENT_STATE_FREE, true);
  403. }
  404. break;
  405. case INNER_STATE_RING_BACK:
  406. {
  407. if(m_State == AGENT_STATE_POST_PROCESSING || m_State == AGENT_STATE_REPOSE || m_State == AGENT_STATE_REQUESTED)
  408. setState(AGENT_STATE_FREE, true);
  409. }
  410. break;
  411. case INNER_STATE_TALKING:
  412. {
  413. if(pCmd == NULL || pCmd->GetDataUInt(10) != PDU_CMD_AGENT_MONI_REPLACE) // 如果是代接操作则不记录应答次数
  414. m_AnswerCount++; // 累计应答计数
  415. setState(AGENT_STATE_BUSY, true);
  416. }
  417. break;
  418. case INNER_STATE_FREE:
  419. {
  420. if(m_State == AGENT_STATE_BUSY)
  421. {
  422. ASSERT(pCmd != NULL);
  423. // 关联线路为非内线,最后通话分机为当前分机,则需要进行话后处理
  424. if(pCmd != NULL && pCmd->GetDataUInt(7) != DEV_RES_TYPE_EXT && pCmd->GetDataUInt(9) == m_Exten)
  425. setState(AGENT_STATE_POST_PROCESSING);
  426. else
  427. setState(AGENT_STATE_FREE, true);
  428. }
  429. else if(m_State == AGENT_STATE_UNKNOWN || m_State == AGENT_STATE_REQUESTED)
  430. setState(AGENT_STATE_FREE, true);
  431. }
  432. break;
  433. default:
  434. {
  435. if(m_State == AGENT_STATE_UNKNOWN)
  436. setState(AGENT_STATE_FREE);
  437. }
  438. break;
  439. }
  440. }
  441. /*****************************************************************
  442. **【函数名称】 lock
  443. **【函数功能】 锁定座席
  444. **【参数】
  445. **【返回值】
  446. ****************************************************************/
  447. BOOL CAgent::lock( void )
  448. {
  449. if(isFree())
  450. return setState(AGENT_STATE_REQUESTED);
  451. else
  452. return FALSE;
  453. }