多数据源中间件标准版1.0

Agent.cpp 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852
  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, m_Exten, 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, m_Exten, 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, m_Exten, 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. setFreeForAgentCall(); // 2020-04-03 根据安图修改 座席置忙外呼后座席设置置忙
  273. }
  274. }
  275. /*****************************************************************
  276. **【函数名称】 __onTimerLock
  277. **【函数功能】 座席被锁定超时处理
  278. **【参数】
  279. **【返回值】
  280. ****************************************************************/
  281. void CAgent::__onTimerLock(void)
  282. {
  283. if (m_State == AGENT_STATE_REQUESTED)
  284. {
  285. //setState(AGENT_STATE_FREE, true);
  286. setFreeForAgentCall(true); // 2020-04-03 根据安图修改 座席置忙外呼后座席设置置忙
  287. }
  288. }
  289. /*****************************************************************
  290. **【函数名称】 __setTimer
  291. **【函数功能】 设立定时器
  292. **【参数】
  293. **【返回值
  294. ****************************************************************/
  295. void CAgent::__setTimer(UINT TimmerId, UINT Elapse)
  296. {
  297. if (TimmerId == TIMER_POST_PROCESSING)
  298. {
  299. m_AgentTimer.StopSafely();
  300. m_AgentTimer.SetTimedEvent(this, &CAgent::__onTimerPostProcessing);
  301. m_AgentTimer.Start(Elapse, false, true, WT_EXECUTEDEFAULT);
  302. }
  303. else if (TimmerId == TIMER_LOCK_PERIOD)
  304. {
  305. m_AgentTimer.StopSafely();
  306. m_AgentTimer.SetTimedEvent(this, &CAgent::__onTimerLock);
  307. m_AgentTimer.Start(Elapse, false, true, WT_EXECUTEDEFAULT);
  308. }
  309. else
  310. {
  311. ASSERT(FALSE);
  312. }
  313. }
  314. /*****************************************************************
  315. **【函数名称】 __killTimer
  316. **【函数功能】 删除定时器
  317. **【参数】
  318. **【返回值
  319. ****************************************************************/
  320. void CAgent::__killTimer(UINT TimmerId)
  321. {
  322. m_AgentTimer.Stop();
  323. }
  324. /*****************************************************************
  325. **【函数名称】 release
  326. **【函数功能】 清理资源
  327. **【参数】 HostAgent: 主控制坐席工号
  328. **【返回值】
  329. ****************************************************************/
  330. void CAgent::release(UINT HostAgent)
  331. {
  332. m_PollTimer.StopSafely();
  333. m_AgentTimer.StopSafely();
  334. // 设置状态为注销
  335. setState(AGENT_STATE_LOGOUT);
  336. // 通知统计模块 REP_EVENT_LOGOUT
  337. __reportLogout(HostAgent);
  338. // 关闭Agent端SOCKET连接
  339. CNetworkAcd::GetInstance().shutDownAgentLink(m_AgentID);
  340. // 添加消息可供视图刷新
  341. CMsgCenter::GetInstance().pushMsg(ACD_MSG_AGENT_LOGOUT, (const PARAM)m_AgentID);
  342. }
  343. /*****************************************************************
  344. **【函数名称】 setState
  345. **【函数功能】 设置座席状态
  346. **【参数】 a_AgentState:座席当前逻辑状态
  347. **【返回值】
  348. ****************************************************************/
  349. BOOL CAgent::setState(AGENT_STATE a_AgentState, bool IsForce/* = false*/)
  350. {
  351. CSingleLock Locker(&m_Cs4Lock, TRUE);
  352. switch (a_AgentState)
  353. {
  354. case AGENT_STATE_BUSY: // 通话
  355. {
  356. switch (m_State)
  357. {
  358. case AGENT_STATE_BUSY:
  359. __reportStatus(); // 2020-04-03 根据安图修改 座席置忙外呼后座席设置置忙
  360. return TRUE;
  361. break;
  362. case AGENT_STATE_REQUESTED:
  363. __killTimer(TIMER_LOCK_PERIOD);
  364. break;
  365. case AGENT_STATE_POST_PROCESSING:
  366. {
  367. __killTimer(TIMER_POST_PROCESSING);
  368. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  369. }
  370. break;
  371. case AGENT_STATE_REPOSE:
  372. {
  373. m_IsRepose = false;
  374. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  375. }
  376. break;
  377. case AGENT_STATE_LOGOUT:
  378. return FALSE;
  379. break;
  380. }
  381. __onStatusUpdate(AGENT_STATE_BUSY, true);
  382. m_State = AGENT_STATE_BUSY;
  383. }
  384. break;
  385. case AGENT_STATE_REPOSE: // 小休
  386. {
  387. switch (m_State)
  388. {
  389. case AGENT_STATE_REPOSE:
  390. m_IsRepose = true; // 2020-04-03 根据安图修改 座席置忙外呼后座席设置置忙
  391. __reportStatus(); // 2020-04-03 根据安图修改 座席置忙外呼后座席设置置忙
  392. return TRUE;
  393. break;
  394. case AGENT_STATE_POST_PROCESSING:
  395. {
  396. __killTimer(TIMER_POST_PROCESSING);
  397. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  398. }
  399. break;
  400. case AGENT_STATE_BUSY:
  401. case AGENT_STATE_LOGOUT:
  402. case AGENT_STATE_REQUESTED:
  403. return FALSE;
  404. break;
  405. }
  406. m_ReposeCount++;
  407. m_IsRepose = true;
  408. m_State = AGENT_STATE_REPOSE;
  409. // 统计小休开始
  410. __onStatusUpdate(AGENT_STATE_REPOSE, true);
  411. }
  412. break;
  413. case AGENT_STATE_POST_PROCESSING: // 话后处理
  414. {
  415. // 电话挂断后重新计算空闲时长 2020-03-05
  416. YamlConfig* fig = YamlConfig::GetInstance();
  417. if (!fig->GetIsUsed()&&fig->GetIsResetFreeTime())
  418. {
  419. m_TimeFree = 0;
  420. }
  421. //
  422. switch (m_State)
  423. {
  424. case AGENT_STATE_POST_PROCESSING:
  425. __reportStatus(); // 2020-04-03 根据安图修改 座席置忙外呼后座席设置置忙
  426. return TRUE;
  427. break;
  428. case AGENT_STATE_BUSY:
  429. __onStatusUpdate(AGENT_STATE_BUSY, false);
  430. break;
  431. case AGENT_STATE_FREE:
  432. case AGENT_STATE_REPOSE:
  433. case AGENT_STATE_REQUESTED:
  434. case AGENT_STATE_LOGOUT:
  435. return FALSE;
  436. break;
  437. }
  438. // 统计话后处理开始
  439. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, true);
  440. m_State = AGENT_STATE_POST_PROCESSING;
  441. //if (m_TimePostProcessing > 0)
  442. // __setTimer(TIMER_POST_PROCESSING, m_TimePostProcessing * 1000); // 启动话后处理定时器
  443. if (m_TimePostProcessing > 0 && m_TypePostProcessing==0) // 2020-03-02
  444. __setTimer(TIMER_POST_PROCESSING, m_TimePostProcessing * 1000); // 启动话后处理定时器
  445. }
  446. break;
  447. case AGENT_STATE_FREE: // 空闲
  448. {
  449. switch (m_State)
  450. {
  451. case AGENT_STATE_FREE:
  452. m_IsRepose = false; // 2020-04-03 根据安图修改 座席置忙外呼后座席设置置忙
  453. __reportStatus(); // 2020-04-03 根据安图修改 座席置忙外呼后座席设置置忙
  454. return TRUE;
  455. break;
  456. case AGENT_STATE_BUSY:
  457. {
  458. if (IsForce)
  459. __onStatusUpdate(AGENT_STATE_BUSY, false);
  460. else
  461. return FALSE;
  462. }
  463. break;
  464. case AGENT_STATE_POST_PROCESSING:
  465. {
  466. __killTimer(TIMER_POST_PROCESSING);
  467. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  468. }
  469. break;
  470. case AGENT_STATE_REPOSE:
  471. {
  472. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  473. m_IsRepose = false;
  474. }
  475. break;
  476. case AGENT_STATE_REQUESTED:
  477. {
  478. if (IsForce)
  479. __killTimer(TIMER_LOCK_PERIOD);
  480. else
  481. return FALSE;
  482. }
  483. break;
  484. case AGENT_STATE_LOGOUT:
  485. return FALSE;
  486. break;
  487. }
  488. m_State = m_IsRepose ? AGENT_STATE_REPOSE : AGENT_STATE_FREE;
  489. }
  490. break;
  491. case AGENT_STATE_REQUESTED: // 被请求
  492. {
  493. ASSERT(m_State == AGENT_STATE_FREE);
  494. switch (m_State)
  495. {
  496. case AGENT_STATE_REQUESTED:
  497. case AGENT_STATE_BUSY:
  498. case AGENT_STATE_REPOSE:
  499. case AGENT_STATE_POST_PROCESSING:
  500. case AGENT_STATE_LOGOUT:
  501. __reportStatus(); // 2020-04-03 根据安图修改 座席置忙外呼后座席设置置忙
  502. return FALSE;
  503. break;
  504. }
  505. __setTimer(TIMER_LOCK_PERIOD, CConfig::agentLockedPeriod() * 1000); // 被请求超时处理定时器
  506. m_State = AGENT_STATE_REQUESTED;
  507. }
  508. break;
  509. default:
  510. {
  511. switch (m_State)
  512. {
  513. case AGENT_STATE_BUSY:
  514. __onStatusUpdate(AGENT_STATE_BUSY, false);
  515. break;
  516. case AGENT_STATE_POST_PROCESSING:
  517. {
  518. __killTimer(TIMER_POST_PROCESSING);
  519. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  520. }
  521. break;
  522. case AGENT_STATE_REPOSE:
  523. {
  524. m_IsRepose = false;
  525. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  526. }
  527. break;
  528. case AGENT_STATE_REQUESTED:
  529. //__killTimer(TIMER_LOCK_PERIOD);
  530. if (a_AgentState != AGENT_STATE_LOGOUT) // 2020-04-03 根据安图修改 座席置忙外呼后座席设置置忙
  531. {
  532. __killTimer(TIMER_LOCK_PERIOD);
  533. }
  534. else // 被请求或者座席锁定签出失败
  535. {
  536. return FALSE;
  537. }
  538. break;
  539. }
  540. m_State = a_AgentState;
  541. }
  542. break;
  543. } // end switch
  544. // 通知座席当前状态变化
  545. __reportStatus();
  546. return TRUE;
  547. }
  548. BOOL CAgent::setFreeForAgentCall(bool IsForce)
  549. {
  550. switch (m_State)
  551. {
  552. case AGENT_STATE_FREE:
  553. return TRUE;
  554. break;
  555. case AGENT_STATE_BUSY:
  556. {
  557. if (IsForce)
  558. __onStatusUpdate(AGENT_STATE_BUSY, false);
  559. else
  560. return FALSE;
  561. }
  562. break;
  563. case AGENT_STATE_POST_PROCESSING:
  564. {
  565. __killTimer(TIMER_POST_PROCESSING);
  566. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  567. }
  568. break;
  569. case AGENT_STATE_REPOSE:
  570. {
  571. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  572. //m_IsRepose = false;
  573. }
  574. break;
  575. case AGENT_STATE_REQUESTED:
  576. {
  577. if (IsForce)
  578. __killTimer(TIMER_LOCK_PERIOD);
  579. else
  580. return FALSE;
  581. }
  582. break;
  583. case AGENT_STATE_LOGOUT:
  584. return FALSE;
  585. break;
  586. }
  587. m_State = AGENT_STATE_FREE;
  588. if (m_IsRepose == false)
  589. __reportStatus();
  590. return TRUE;
  591. }
  592. BOOL CAgent::setRequestedForAgentCall(bool IsForce)
  593. {
  594. ASSERT(m_State == AGENT_STATE_FREE);
  595. switch (m_State)
  596. {
  597. case AGENT_STATE_REQUESTED:
  598. case AGENT_STATE_BUSY:
  599. case AGENT_STATE_REPOSE:
  600. case AGENT_STATE_POST_PROCESSING:
  601. case AGENT_STATE_LOGOUT:
  602. return FALSE;
  603. break;
  604. }
  605. __setTimer(TIMER_LOCK_PERIOD, CConfig::agentLockedPeriod() * 1000); // 被请求超时处理定时器
  606. m_State = AGENT_STATE_REQUESTED;
  607. if (m_IsRepose == false)
  608. __reportStatus();
  609. return TRUE;
  610. }
  611. BOOL CAgent::setBusyForAgentCall(bool IsForce)
  612. {
  613. switch (m_State)
  614. {
  615. case AGENT_STATE_BUSY:
  616. return TRUE;
  617. break;
  618. case AGENT_STATE_REQUESTED:
  619. __killTimer(TIMER_LOCK_PERIOD);
  620. break;
  621. case AGENT_STATE_POST_PROCESSING:
  622. {
  623. __killTimer(TIMER_POST_PROCESSING);
  624. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, false);
  625. }
  626. break;
  627. case AGENT_STATE_REPOSE:
  628. {
  629. //m_IsRepose = false;
  630. __onStatusUpdate(AGENT_STATE_REPOSE, false);
  631. }
  632. break;
  633. case AGENT_STATE_LOGOUT:
  634. return FALSE;
  635. break;
  636. }
  637. __onStatusUpdate(AGENT_STATE_BUSY, true);
  638. m_State = AGENT_STATE_BUSY;
  639. if (m_IsRepose == false)
  640. __reportStatus();
  641. return TRUE;
  642. }
  643. BOOL CAgent::setProcessingForAgentCall(bool IsForce)
  644. {
  645. switch (m_State)
  646. {
  647. case AGENT_STATE_POST_PROCESSING:
  648. return TRUE;
  649. break;
  650. case AGENT_STATE_BUSY:
  651. __onStatusUpdate(AGENT_STATE_BUSY, false);
  652. break;
  653. case AGENT_STATE_FREE:
  654. case AGENT_STATE_REPOSE:
  655. case AGENT_STATE_REQUESTED:
  656. case AGENT_STATE_LOGOUT:
  657. return FALSE;
  658. break;
  659. }
  660. // 统计话后处理开始
  661. __onStatusUpdate(AGENT_STATE_POST_PROCESSING, true);
  662. m_State = AGENT_STATE_POST_PROCESSING;
  663. if (m_TimePostProcessing > 0)
  664. __setTimer(TIMER_POST_PROCESSING, m_TimePostProcessing * 1000); // 启动话后处理定时器
  665. if (m_IsRepose == false)
  666. __reportStatus();
  667. return TRUE;
  668. }
  669. /*****************************************************************
  670. **【函数名称】 onAssoExtStatusUpdated
  671. **【函数功能】 关联分机状态更新的处理函数
  672. **【参数】 a_ExtState:分机当前状态
  673. Param:附加参数
  674. **【返回值】
  675. ****************************************************************/
  676. void CAgent::onAssoExtStatusUpdated(INNER_STATE a_ExtState, PARAM Param /*= NULL*/)
  677. {
  678. CPduEntity * pCmd = (CPduEntity *)Param;
  679. m_AssoExtState = a_ExtState;
  680. switch (a_ExtState)
  681. {
  682. case INNER_STATE_ALERTING:
  683. {
  684. if (m_State == AGENT_STATE_POST_PROCESSING || m_State == AGENT_STATE_REPOSE /*|| m_State == AGENT_STATE_REQUESTED*/)
  685. setFreeForAgentCall(true);
  686. //setState(AGENT_STATE_FREE, true);
  687. }
  688. break;
  689. case INNER_STATE_RING_BACK:
  690. {
  691. if (m_State == AGENT_STATE_POST_PROCESSING || m_State == AGENT_STATE_REPOSE || m_State == AGENT_STATE_REQUESTED)
  692. setFreeForAgentCall(true);
  693. //setState(AGENT_STATE_FREE, true);
  694. }
  695. break;
  696. case INNER_STATE_TALKING:
  697. {
  698. if (pCmd == NULL || pCmd->GetDataUInt(10) != PDU_CMD_AGENT_MONI_REPLACE) // 如果是代接操作则不记录应答次数
  699. m_AnswerCount++; // 累计应答计数
  700. //setState(AGENT_STATE_BUSY, true);
  701. setBusyForAgentCall(true);
  702. }
  703. break;
  704. case INNER_STATE_FREE:
  705. {
  706. if (m_State == AGENT_STATE_BUSY)
  707. {
  708. ASSERT(pCmd != NULL);
  709. // 关联线路为非内线,最后通话分机为当前分机,则需要进行话后处理
  710. if (pCmd != NULL && pCmd->GetDataUInt(7) != DEV_RES_TYPE_EXT && pCmd->GetDataUInt(9) == m_Exten)
  711. //setState(AGENT_STATE_POST_PROCESSING);
  712. setProcessingForAgentCall();
  713. else
  714. //setState(AGENT_STATE_FREE, true);
  715. setFreeForAgentCall(true);
  716. }
  717. else if (m_State == AGENT_STATE_UNKNOWN || m_State == AGENT_STATE_REQUESTED)
  718. //setState(AGENT_STATE_FREE, true);
  719. setFreeForAgentCall(true);
  720. }
  721. break;
  722. default:
  723. {
  724. if (m_State == AGENT_STATE_UNKNOWN)
  725. setState(AGENT_STATE_FREE);
  726. }
  727. break;
  728. }
  729. }
  730. /*****************************************************************
  731. **【函数名称】 lock
  732. **【函数功能】 锁定座席
  733. **【参数】
  734. **【返回值】
  735. ****************************************************************/
  736. BOOL CAgent::lock(void)
  737. {
  738. if (isFree())
  739. return setState(AGENT_STATE_REQUESTED);
  740. else
  741. return FALSE;
  742. }
  743. BOOL CAgent::lockForCall(void)
  744. {
  745. if (isFreeForCall())
  746. return setRequestedForAgentCall();
  747. //return setState(AGENT_STATE_REQUESTED);
  748. else
  749. return FALSE;
  750. }
  751. //void CAgent::GetAgentProperty(CAgentProperty& AgentProperty)
  752. //{
  753. // AgentProperty.m_AnswerCount = m_AnswerCount;
  754. // AgentProperty.m_ReposeCount = m_ReposeCount;
  755. // AgentProperty.m_TimeFree = m_TimeFree;
  756. // AgentProperty.m_TimePostProcessing = m_TimePostProcessing;
  757. // AgentProperty.m_TimeRepos = m_TimeRepos;
  758. // AgentProperty.m_TimeTalk = m_TimeTalk;
  759. //}
  760. bool CAgent::queueJump()
  761. {
  762. if (m_bFirstQueue) {
  763. m_bFirstQueue = false;
  764. return true;
  765. }
  766. else
  767. {
  768. return false;
  769. }
  770. }