中航光电的中间件仓库

Agent - 副本.cpp 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  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. #include "Exten.h"
  9. #include "YamlConfig.h"
  10. CAgent::CAgent(UINT a_AgentID, UINT a_ExtID, LPCTSTR a_GroupID, UINT a_AgentType, UINT a_PostProcessingTime)
  11. {
  12. // 网络属性
  13. CNetworkAcd::GetInstance().getAgentLinkInfo(a_AgentID, m_AgentIp, m_AgentPort);
  14. // 基本属性
  15. m_AgentID = a_AgentID;
  16. m_Exten = a_ExtID;
  17. m_GroupID = a_GroupID;
  18. m_AgentType = (AGENT_TYPE)a_AgentType;
  19. m_State = AGENT_STATE_UNKNOWN;
  20. m_AssoExtState = INNER_STATE_FREE;
  21. m_IsRepose = false;
  22. m_bFirstQueue = true;
  23. // 业务属性
  24. m_AnswerCount = 0;
  25. m_ReposeCount = 0;
  26. m_TimeFree = 0;
  27. m_TimeRepos = 0;
  28. m_TimeTalk = 0;
  29. m_TypePostProcessing = CConfig::postProcessingType(); //2020-03-02 话后处理类型
  30. m_TimePostProcessing = (a_PostProcessingTime == 0) ? CConfig::postProcessingTime() : a_PostProcessingTime;
  31. /*******************2019-12-19**********************/
  32. m_AnswerCountOld = 0;
  33. m_ReposeCountOld = 0;
  34. m_TimeFreeOld = 0;
  35. m_TimeReposOld = 0;
  36. m_TimeTalkOld = 0;
  37. CString curDay;
  38. CTime tm;
  39. tm = CTime::GetCurrentTime();
  40. curDay = tm.Format("%Y-%m-%d ");
  41. CString startTime, endTime;
  42. startTime = "00:00";
  43. endTime = "23:59";
  44. startTime = curDay + startTime;
  45. endTime = curDay + endTime;
  46. YamlConfig* fig = YamlConfig::GetInstance();
  47. if (fig->GetIsUsed())
  48. {
  49. map<string, string> m_Times = fig->GetTimeMap();
  50. if (m_Times.size() > 0)
  51. {
  52. map<string, string>::iterator it = m_Times.begin();
  53. while (it != m_Times.end())
  54. {
  55. CTime ts = YamlConfig::timestr((curDay.GetString() + it->first).c_str()); // 开始时间
  56. CTime te = YamlConfig::timestr((curDay.GetString() + it->second).c_str()); // 结束时间
  57. if (ts > te) // 如果开始时间大于结束时间,则结束时间为第二天的时间
  58. te = te + CTimeSpan(1, 0, 0, 0);
  59. if (tm > ts && tm < te) // 当前时间在该时间段内则使用该考核时间段
  60. {
  61. startTime = ts.Format("%Y-%m-%d %H:%M");
  62. endTime = te.Format("%Y-%m-%d %H:%M");
  63. cout << startTime << "**" << endTime << endl;
  64. break;
  65. }
  66. cout << startTime << "遍历" << endTime << endl;
  67. ++it;
  68. }
  69. }
  70. CString sql;
  71. sql.Format("SELECT sum([FreeTimes])[FreeTimes],sum([ReposeTimes])[ReposeTimes] ,sum([TalkTimes])[TalkTimes] ,sum([ReposeNum])[ReposeNum],sum([AnswerNum])[AnswerNum] "
  72. "FROM [dbo].[rep_agent_detail] where AgentId = %d and TimeLogin between '%s' and '%s'", a_AgentID, startTime, endTime);
  73. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, "初始化座席信息sql:%s", sql);
  74. IOtlConnection* pConn = IOtlConnection::getInstance();
  75. IOtlRecordset* record = pConn->QueryRecords(sql);
  76. if (record != NULL)
  77. {
  78. if (!record->IsEOF())
  79. {
  80. record->MoveNextRow();
  81. m_AnswerCountOld = record->GetValueInt("AnswerNum");
  82. m_ReposeCountOld = record->GetValueInt("ReposeNum");
  83. m_TimeFreeOld = record->GetValueInt("FreeTimes");
  84. m_TimeReposOld = record->GetValueInt("ReposeTimes");
  85. m_TimeTalkOld = record->GetValueInt("TalkTimes");
  86. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, "初始化座席业务信息:AnswerNum = %d,ReposeNum = %d,FreeTimes = %d,ReposeTimes = %d,TalkTimes = %d", m_AnswerCountOld, m_ReposeCountOld, m_TimeFreeOld, m_TimeReposOld, m_TimeTalkOld);
  87. }
  88. }
  89. IOtlRecordset::DestroyInstance(record); // 释放记录集
  90. }
  91. /*************************************************/
  92. // 定时器初始化
  93. m_PollTimer.SetTimedEvent(this, &CAgent::__onTimerPoll);
  94. m_PollTimer.Start(1000);
  95. // 通知统计模块座席签入
  96. __reportLogin();
  97. // 添加消息可供视图刷新
  98. CMsgCenter::GetInstance().pushMsg(ACD_MSG_AGENT_STATE_UPDAET, (const PARAM)m_AgentID);
  99. }
  100. //CAgent::CAgent(UINT a_AgentID, UINT a_ExtID, LPCTSTR a_GroupID, UINT a_AgentType, const CAgentProperty& AgentProperty)
  101. //{
  102. // // 网络属性
  103. // CNetworkAcd::GetInstance().getAgentLinkInfo(a_AgentID, m_AgentIp, m_AgentPort);
  104. //
  105. // // 基本属性
  106. // m_AgentID = a_AgentID;
  107. // m_Exten = a_ExtID;
  108. // m_GroupID = a_GroupID;
  109. // m_AgentType = (AGENT_TYPE)a_AgentType;
  110. // m_State = AGENT_STATE_UNKNOWN;
  111. // m_AssoExtState = INNER_STATE_FREE;
  112. // m_IsRepose = false;
  113. //
  114. // // 业务属性
  115. // m_AnswerCount = AgentProperty.m_AnswerCount;
  116. // m_ReposeCount = AgentProperty.m_ReposeCount;
  117. // m_TimeFree = AgentProperty.m_TimeFree;
  118. // m_TimeRepos = AgentProperty.m_TimeRepos;
  119. // m_TimeTalk = AgentProperty.m_TimeTalk;
  120. // m_TimePostProcessing = (AgentProperty.m_TimePostProcessing == 0) ? CConfig::postProcessingTime() : AgentProperty.m_TimePostProcessing;
  121. //
  122. // // 定时器初始化
  123. // m_PollTimer.SetTimedEvent(this, &CAgent::__onTimerPoll);
  124. // m_PollTimer.Start(1000);
  125. // // 通知统计模块座席签入
  126. // __reportLogin();
  127. //
  128. // // 添加消息可供视图刷新
  129. // CMsgCenter::GetInstance().pushMsg(ACD_MSG_AGENT_STATE_UPDAET, (const PARAM)m_AgentID);
  130. //}
  131. CAgent::~CAgent(void)
  132. {
  133. m_PollTimer.StopSafely();
  134. m_AgentTimer.StopSafely();
  135. }
  136. /*****************************************************************
  137. **【函数名称】 __reportLogin
  138. **【函数功能】 签出统计通知
  139. **【参数】
  140. **【返回值】
  141. ****************************************************************/
  142. void CAgent::__reportLogin()
  143. {
  144. // 通知统计模块 REP_EVENT_LOGIN
  145. T_EvtLogIn repLogin = { 0 };
  146. repLogin.nAgentID = m_AgentID;
  147. repLogin.nExtID = m_Exten;
  148. repLogin.nAgentType = m_AgentType;
  149. lstrcpy(repLogin.szGroup, m_GroupID);
  150. lstrcpy(repLogin.szAgentIP, m_AgentIp);
  151. CSLogic::GetInstance().onSEvent(m_AgentID, REP_EVENT_LOGIN, &repLogin);
  152. }
  153. /*****************************************************************
  154. **【函数名称】 __reportLogout
  155. **【函数功能】 签出统计通知
  156. **【参数】 HostAgent: 签出当前座席的主控座席
  157. **【返回值】
  158. ****************************************************************/
  159. void CAgent::__reportLogout(const UINT HostAgent)
  160. {
  161. if (m_State == AGENT_STATE_REPOSE)
  162. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  163. if (m_State == AGENT_STATE_POST_PROCESSING)
  164. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  165. // 通知统计模块 REP_EVENT_LOGOUT
  166. T_EvtLogout repLogout = { 0 };
  167. repLogout.nLogoutHost = HostAgent;
  168. repLogout.nTimeFree = m_TimeFree;
  169. repLogout.nTimeRepose = m_TimeRepos;
  170. repLogout.nTimeTalk = m_TimeTalk;
  171. repLogout.nAnswerCount = m_AnswerCount;
  172. repLogout.nReposeCount = m_ReposeCount;
  173. CSLogic::GetInstance().onSEvent(m_AgentID, REP_EVENT_LOGOUT, &repLogout);
  174. }
  175. /*****************************************************************
  176. **【函数名称】 __onStatusUpdate
  177. **【函数功能】 座席状态变更通知
  178. **【参数】
  179. **【返回值】
  180. ****************************************************************/
  181. void CAgent::__onStatusUpdate(AGENT_STATE State, bool StartFlag)
  182. {
  183. T_EvtStatus EvtStatus;
  184. EvtStatus.State = State;
  185. EvtStatus.StartFlag = StartFlag;
  186. CSLogic::GetInstance().onSEvent(m_AgentID, REP_EVENT_STATE, &EvtStatus);
  187. }
  188. /*****************************************************************
  189. **【函数名称】 __reportStatus
  190. **【函数功能】 通知各方座席当前状态
  191. **【参数】
  192. **【返回值】
  193. ****************************************************************/
  194. void CAgent::__reportStatus(void)
  195. {
  196. // 通知OCX座席当前状态
  197. CPduEntity Cmd(PDU_CMD_ACD_AGENT_STATE);
  198. Cmd.SetDataUInt(0, m_Exten);
  199. Cmd.SetDataUInt(1, m_AgentID);
  200. Cmd.SetDataUInt(2, m_State);
  201. //CNetworkAcd::GetInstance().send2Agent(m_AgentID, &Cmd);
  202. CNetworkAcd::GetInstance().send2Server(&Cmd);
  203. // 添加消息可供视图刷新
  204. CMsgCenter::GetInstance().pushMsg(ACD_MSG_AGENT_STATE_UPDAET, (PARAM)m_AgentID);
  205. }
  206. /*****************************************************************
  207. **【函数名称】 __reportStatus
  208. **【函数功能】 通知各方座席当前状态
  209. **【参数】
  210. **【返回值】
  211. ych 2018.5.17
  212. ****************************************************************
  213. void CAgent::__reportStatus(void)
  214. {
  215. CExten* pExten = CAcdCore::GetInstance().getExtenCtrl().getExten(m_Exten); // 获取指定分机
  216. if (pExten == NULL)
  217. {
  218. // 显示日志 ych 2018.5.17
  219. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{CAgent::__reportStatus}: pExten指针为NULL"));
  220. return;
  221. }
  222. if (m_AgentID !=0 && m_AgentID == pExten->assoAgent())
  223. {
  224. CPduEntity Cmd(PDU_CMD_CTI_LINE_STATE);
  225. Cmd.SetDataUInt(0, pExten->GetID());
  226. Cmd.SetDataUInt(1, pExten->GetState());
  227. Cmd.SetDataULong(2, pExten->GetCallId());
  228. Cmd.SetDataUInt(3, pExten->GetAssoAgent());
  229. Cmd.SetDataString(4, pExten->GetCallerNum());
  230. Cmd.SetDataString(5, pExten->GetCalleeNum());
  231. Cmd.SetDataString(6, pExten->GetDataBind());
  232. Cmd.SetDataUInt(7, pExten->GetPeerLineType());
  233. Cmd.SetDataUInt(8, pExten->GetInfoEx());
  234. Cmd.SetDataUInt(9, pExten->GetFinalExt());
  235. Cmd.SetDataUInt(10, pExten->GetOpType());
  236. Cmd.SetDataUInt(11, 0);
  237. Cmd.SetDataUInt(12, m_State);
  238. //CNetworkAcd::GetInstance().send2Agent(m_AssoAgent, &Cmd);
  239. CNetworkAcd::GetInstance().send2Server(&Cmd);
  240. // 显示日志 ych 2018.5.17
  241. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{CAgent::__reportStatus}: 返回线路及座席状态"));
  242. // 添加消息可供视图刷新
  243. CMsgCenter::GetInstance().pushMsg(ACD_MSG_AGENT_STATE_UPDAET, (PARAM)m_AgentID);
  244. }
  245. }*/
  246. /*****************************************************************
  247. **【函数名称】 __onTimerPoll
  248. **【函数功能】 轮询定时器处理
  249. **【参数】
  250. **【返回值】
  251. ****************************************************************/
  252. void CAgent::__onTimerPoll(void)
  253. {
  254. if (m_State == AGENT_STATE_FREE)
  255. m_TimeFree++;
  256. else if (m_State == AGENT_STATE_BUSY)
  257. m_TimeTalk++;
  258. if (m_IsRepose)
  259. m_TimeRepos++;
  260. }
  261. /*****************************************************************
  262. **【函数名称】 __onTimerPostProcessing
  263. **【函数功能】 话后处理时长定时器处理
  264. **【参数】
  265. **【返回值】
  266. ****************************************************************/
  267. void CAgent::__onTimerPostProcessing(void)
  268. {
  269. if (m_State == AGENT_STATE_POST_PROCESSING)
  270. {
  271. setState(AGENT_STATE_FREE);
  272. }
  273. }
  274. /*****************************************************************
  275. **【函数名称】 __onTimerLock
  276. **【函数功能】 座席被锁定超时处理
  277. **【参数】
  278. **【返回值】
  279. ****************************************************************/
  280. void CAgent::__onTimerLock(void)
  281. {
  282. if (m_State == AGENT_STATE_REQUESTED)
  283. {
  284. setState(AGENT_STATE_FREE, true);
  285. }
  286. }
  287. /*****************************************************************
  288. **【函数名称】 __setTimer
  289. **【函数功能】 设立定时器
  290. **【参数】
  291. **【返回值
  292. ****************************************************************/
  293. void CAgent::__setTimer(UINT TimmerId, UINT Elapse)
  294. {
  295. if (TimmerId == TIMER_POST_PROCESSING)
  296. {
  297. m_AgentTimer.StopSafely();
  298. m_AgentTimer.SetTimedEvent(this, &CAgent::__onTimerPostProcessing);
  299. m_AgentTimer.Start(Elapse, false, true, WT_EXECUTEDEFAULT);
  300. }
  301. else if (TimmerId == TIMER_LOCK_PERIOD)
  302. {
  303. m_AgentTimer.StopSafely();
  304. m_AgentTimer.SetTimedEvent(this, &CAgent::__onTimerLock);
  305. m_AgentTimer.Start(Elapse, false, true, WT_EXECUTEDEFAULT);
  306. }
  307. else
  308. {
  309. ASSERT(FALSE);
  310. }
  311. }
  312. /*****************************************************************
  313. **【函数名称】 __killTimer
  314. **【函数功能】 删除定时器
  315. **【参数】
  316. **【返回值
  317. ****************************************************************/
  318. void CAgent::__killTimer(UINT TimmerId)
  319. {
  320. m_AgentTimer.Stop();
  321. }
  322. /*****************************************************************
  323. **【函数名称】 release
  324. **【函数功能】 清理资源
  325. **【参数】 HostAgent: 主控制坐席工号
  326. **【返回值】
  327. ****************************************************************/
  328. void CAgent::release(UINT HostAgent)
  329. {
  330. m_PollTimer.StopSafely();
  331. m_AgentTimer.StopSafely();
  332. // 设置状态为注销
  333. setState(AGENT_STATE_LOGOUT);
  334. // 通知统计模块 REP_EVENT_LOGOUT
  335. __reportLogout(HostAgent);
  336. // 关闭Agent端SOCKET连接
  337. CNetworkAcd::GetInstance().shutDownAgentLink(m_AgentID);
  338. // 添加消息可供视图刷新
  339. CMsgCenter::GetInstance().pushMsg(ACD_MSG_AGENT_LOGOUT, (const PARAM)m_AgentID);
  340. }
  341. /*****************************************************************
  342. **【函数名称】 setState
  343. **【函数功能】 设置座席状态
  344. **【参数】 a_AgentState:座席当前逻辑状态
  345. **【返回值】
  346. ****************************************************************/
  347. BOOL CAgent::setState(AGENT_STATE a_AgentState, bool IsForce/* = false*/)
  348. {
  349. CSingleLock Locker(&m_Cs4Lock, TRUE);
  350. switch (a_AgentState)
  351. {
  352. case AGENT_STATE_BUSY: // 通话
  353. {
  354. switch (m_State)
  355. {
  356. case AGENT_STATE_BUSY:
  357. return TRUE;
  358. break;
  359. case AGENT_STATE_REQUESTED:
  360. __killTimer(TIMER_LOCK_PERIOD);
  361. break;
  362. case AGENT_STATE_POST_PROCESSING:
  363. {
  364. __killTimer(TIMER_POST_PROCESSING);
  365. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  366. }
  367. break;
  368. case AGENT_STATE_REPOSE:
  369. {
  370. m_IsRepose = false;
  371. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  372. }
  373. break;
  374. case AGENT_STATE_LOGOUT:
  375. return FALSE;
  376. break;
  377. }
  378. __onStatusUpdate(AGENT_STATE_BUSY, true);
  379. m_State = AGENT_STATE_BUSY;
  380. }
  381. break;
  382. case AGENT_STATE_REPOSE: // 小休
  383. {
  384. switch (m_State)
  385. {
  386. case AGENT_STATE_REPOSE:
  387. return TRUE;
  388. break;
  389. case AGENT_STATE_POST_PROCESSING:
  390. {
  391. __killTimer(TIMER_POST_PROCESSING);
  392. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  393. }
  394. break;
  395. case AGENT_STATE_BUSY:
  396. case AGENT_STATE_LOGOUT:
  397. case AGENT_STATE_REQUESTED:
  398. return FALSE;
  399. break;
  400. }
  401. m_ReposeCount++;
  402. m_IsRepose = true;
  403. m_State = AGENT_STATE_REPOSE;
  404. // 统计小休开始
  405. __onStatusUpdate(AGENT_STATE_REPOSE, true);
  406. }
  407. break;
  408. case AGENT_STATE_POST_PROCESSING: // 话后处理
  409. {
  410. // 电话挂断后重新计算空闲时长 2020-03-05
  411. YamlConfig* fig = YamlConfig::GetInstance();
  412. if (!fig->GetIsUsed()&&fig->GetIsResetFreeTime())
  413. {
  414. m_TimeFree = 0;
  415. }
  416. //
  417. switch (m_State)
  418. {
  419. case AGENT_STATE_POST_PROCESSING:
  420. return TRUE;
  421. break;
  422. case AGENT_STATE_BUSY:
  423. __onStatusUpdate(AGENT_STATE_BUSY, false);
  424. break;
  425. case AGENT_STATE_FREE:
  426. case AGENT_STATE_REPOSE:
  427. case AGENT_STATE_REQUESTED:
  428. case AGENT_STATE_LOGOUT:
  429. return FALSE;
  430. break;
  431. }
  432. // 统计话后处理开始
  433. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, true);
  434. m_State = AGENT_STATE_POST_PROCESSING;
  435. //if (m_TimePostProcessing > 0)
  436. // __setTimer(TIMER_POST_PROCESSING, m_TimePostProcessing * 1000); // 启动话后处理定时器
  437. if (m_TimePostProcessing > 0 && m_TypePostProcessing==0) // 2020-03-02
  438. __setTimer(TIMER_POST_PROCESSING, m_TimePostProcessing * 1000); // 启动话后处理定时器
  439. }
  440. break;
  441. case AGENT_STATE_FREE: // 空闲
  442. {
  443. switch (m_State)
  444. {
  445. case AGENT_STATE_FREE:
  446. return TRUE;
  447. break;
  448. case AGENT_STATE_BUSY:
  449. {
  450. if (IsForce)
  451. __onStatusUpdate(AGENT_STATE_BUSY, false);
  452. else
  453. return FALSE;
  454. }
  455. break;
  456. case AGENT_STATE_POST_PROCESSING:
  457. {
  458. __killTimer(TIMER_POST_PROCESSING);
  459. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  460. }
  461. break;
  462. case AGENT_STATE_REPOSE:
  463. {
  464. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  465. m_IsRepose = false;
  466. }
  467. break;
  468. case AGENT_STATE_REQUESTED:
  469. {
  470. if (IsForce)
  471. __killTimer(TIMER_LOCK_PERIOD);
  472. else
  473. return FALSE;
  474. }
  475. break;
  476. case AGENT_STATE_LOGOUT:
  477. return FALSE;
  478. break;
  479. }
  480. m_State = m_IsRepose ? AGENT_STATE_REPOSE : AGENT_STATE_FREE;
  481. }
  482. break;
  483. case AGENT_STATE_REQUESTED: // 被请求
  484. {
  485. ASSERT(m_State == AGENT_STATE_FREE);
  486. switch (m_State)
  487. {
  488. case AGENT_STATE_REQUESTED:
  489. case AGENT_STATE_BUSY:
  490. case AGENT_STATE_REPOSE:
  491. case AGENT_STATE_POST_PROCESSING:
  492. case AGENT_STATE_LOGOUT:
  493. return FALSE;
  494. break;
  495. }
  496. __setTimer(TIMER_LOCK_PERIOD, CConfig::agentLockedPeriod() * 1000); // 被请求超时处理定时器
  497. m_State = AGENT_STATE_REQUESTED;
  498. }
  499. break;
  500. default:
  501. {
  502. switch (m_State)
  503. {
  504. case AGENT_STATE_BUSY:
  505. __onStatusUpdate(AGENT_STATE_BUSY, false);
  506. break;
  507. case AGENT_STATE_POST_PROCESSING:
  508. {
  509. __killTimer(TIMER_POST_PROCESSING);
  510. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  511. }
  512. break;
  513. case AGENT_STATE_REPOSE:
  514. {
  515. m_IsRepose = false;
  516. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  517. }
  518. break;
  519. case AGENT_STATE_REQUESTED:
  520. __killTimer(TIMER_LOCK_PERIOD);
  521. break;
  522. }
  523. m_State = a_AgentState;
  524. }
  525. break;
  526. } // end switch
  527. // 通知座席当前状态变化
  528. __reportStatus();
  529. return TRUE;
  530. }
  531. /*****************************************************************
  532. **【函数名称】 onAssoExtStatusUpdated
  533. **【函数功能】 关联分机状态更新的处理函数
  534. **【参数】 a_ExtState:分机当前状态
  535. Param:附加参数
  536. **【返回值】
  537. ****************************************************************/
  538. void CAgent::onAssoExtStatusUpdated(INNER_STATE a_ExtState, PARAM Param /*= NULL*/)
  539. {
  540. CPduEntity * pCmd = (CPduEntity *)Param;
  541. m_AssoExtState = a_ExtState;
  542. switch (a_ExtState)
  543. {
  544. case INNER_STATE_ALERTING:
  545. {
  546. if (m_State == AGENT_STATE_POST_PROCESSING || m_State == AGENT_STATE_REPOSE /*|| m_State == AGENT_STATE_REQUESTED*/)
  547. setState(AGENT_STATE_FREE, true);
  548. }
  549. break;
  550. case INNER_STATE_RING_BACK:
  551. {
  552. if (m_State == AGENT_STATE_POST_PROCESSING || m_State == AGENT_STATE_REPOSE || m_State == AGENT_STATE_REQUESTED)
  553. setState(AGENT_STATE_FREE, true);
  554. }
  555. break;
  556. case INNER_STATE_TALKING:
  557. {
  558. if (pCmd == NULL || pCmd->GetDataUInt(10) != PDU_CMD_AGENT_MONI_REPLACE) // 如果是代接操作则不记录应答次数
  559. m_AnswerCount++; // 累计应答计数
  560. setState(AGENT_STATE_BUSY, true);
  561. }
  562. break;
  563. case INNER_STATE_FREE:
  564. {
  565. if (m_State == AGENT_STATE_BUSY)
  566. {
  567. ASSERT(pCmd != NULL);
  568. // 关联线路为非内线,最后通话分机为当前分机,则需要进行话后处理
  569. if (pCmd != NULL && pCmd->GetDataUInt(7) != DEV_RES_TYPE_EXT && pCmd->GetDataUInt(9) == m_Exten)
  570. setState(AGENT_STATE_POST_PROCESSING);
  571. else
  572. setState(AGENT_STATE_FREE, true);
  573. }
  574. else if (m_State == AGENT_STATE_UNKNOWN || m_State == AGENT_STATE_REQUESTED)
  575. setState(AGENT_STATE_FREE, true);
  576. }
  577. break;
  578. default:
  579. {
  580. if (m_State == AGENT_STATE_UNKNOWN)
  581. setState(AGENT_STATE_FREE);
  582. }
  583. break;
  584. }
  585. }
  586. /*****************************************************************
  587. **【函数名称】 lock
  588. **【函数功能】 锁定座席
  589. **【参数】
  590. **【返回值】
  591. ****************************************************************/
  592. BOOL CAgent::lock(void)
  593. {
  594. if (isFree())
  595. return setState(AGENT_STATE_REQUESTED);
  596. else
  597. return FALSE;
  598. }
  599. //void CAgent::GetAgentProperty(CAgentProperty& AgentProperty)
  600. //{
  601. // AgentProperty.m_AnswerCount = m_AnswerCount;
  602. // AgentProperty.m_ReposeCount = m_ReposeCount;
  603. // AgentProperty.m_TimeFree = m_TimeFree;
  604. // AgentProperty.m_TimePostProcessing = m_TimePostProcessing;
  605. // AgentProperty.m_TimeRepos = m_TimeRepos;
  606. // AgentProperty.m_TimeTalk = m_TimeTalk;
  607. //}
  608. bool CAgent::queueJump()
  609. {
  610. if (m_bFirstQueue) {
  611. m_bFirstQueue = false;
  612. return true;
  613. }
  614. else
  615. {
  616. return false;
  617. }
  618. }