Brak opisu

AgentOffice.cpp 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. #include "StdAfx.h"
  2. #include "AgentOffice.h"
  3. #include "Agent.h"
  4. #include "AcdCore.h"
  5. #include "ExtenCtrl.h"
  6. #include "MsgCenter.h"
  7. CAgentOffice::CAgentOffice(void)
  8. {
  9. }
  10. CAgentOffice::~CAgentOffice(void)
  11. {
  12. }
  13. /*****************************************************************
  14. **【函数名称】 getAgentById
  15. **【函数功能】 根据工号查找座席对象
  16. **【参数】 AgentId: 要查找的座席工号
  17. **【返回值】 对应工号的座席对象
  18. ****************************************************************/
  19. CAgent* CAgentOffice::getAgentById( UINT AgentId )
  20. {
  21. CSingleLock Lock(&m_Cs4AgentMap, TRUE);
  22. CAgent* pAgent = NULL;
  23. m_AgentMap.Lookup(AgentId, pAgent);
  24. return pAgent;
  25. }
  26. /*****************************************************************
  27. **【函数名称】 getAgentByExt
  28. **【函数功能】 根据分机号查找座席对象
  29. **【参数】
  30. **【返回值】 对应工号的座席对象
  31. ****************************************************************/
  32. CAgent* CAgentOffice::getAgentByExt( UINT AgentId, UINT ExtenId )
  33. {
  34. CSingleLock Lock(&m_Cs4AgentMap, TRUE);
  35. CAgent* pAgent = NULL;
  36. if(m_AgentMap.Lookup(AgentId, pAgent))
  37. {
  38. if(pAgent->assoExten() == ExtenId)
  39. return pAgent;
  40. }
  41. return NULL;
  42. }
  43. /*****************************************************************
  44. **【函数名称】 getAgentByIp
  45. **【函数功能】 根据工号及IP查找座席对象
  46. **【参数】 AgentId: 要查找的座席工号
  47. AgentIp: 座席IP
  48. **【返回值】 对应工号及IP的座席对象
  49. ****************************************************************/
  50. CAgent* CAgentOffice::getAgentByIp( UINT AgentId, const CString& AgentIp )
  51. {
  52. CSingleLock Lock(&m_Cs4AgentMap, TRUE);
  53. CAgent* pAgent = NULL;
  54. if(m_AgentMap.Lookup(AgentId, pAgent))
  55. {
  56. if(pAgent->ip() == AgentIp)
  57. return pAgent;
  58. }
  59. return NULL;
  60. }
  61. /*****************************************************************
  62. **【函数名称】 getAgentInfo
  63. **【函数功能】 获取坐席信息
  64. **【参数】
  65. **【返回值】
  66. ****************************************************************/
  67. BOOL CAgentOffice::getAgentInfo( Agent2Show& Info )
  68. {
  69. CSingleLock Lock(&m_Cs4AgentMap, TRUE);
  70. CAgent* pAgent = NULL;
  71. if(m_AgentMap.Lookup(Info.AgentId, pAgent))
  72. {
  73. Info.ExtId = pAgent->assoExten();
  74. Info.GroupNo = pAgent->group();
  75. Info.AgentType = pAgent->type();
  76. Info.State = pAgent->state();
  77. return TRUE;
  78. }
  79. return FALSE;
  80. }
  81. /*****************************************************************
  82. **【函数名称】 close
  83. **【函数功能】 释放资源
  84. **【参数】
  85. **【返回值】
  86. ****************************************************************/
  87. void CAgentOffice::close( void )
  88. {
  89. clearAgent();
  90. }
  91. /*****************************************************************
  92. **【函数名称】 clearAgent
  93. **【函数功能】 清理所有座席
  94. **【参数】
  95. **【返回值】
  96. ****************************************************************/
  97. void CAgentOffice::clearAgent( void )
  98. {
  99. CSingleLock Lock(&m_Cs4AgentMap, TRUE);
  100. UINT Key;
  101. CAgent* pAgent = NULL;
  102. POSITION Pos = m_AgentMap.GetStartPosition();
  103. // 清除所有座席
  104. while (Pos != NULL)
  105. {
  106. m_AgentMap.GetNextAssoc(Pos, Key, pAgent);
  107. ASSERT(pAgent != NULL);
  108. if (pAgent)
  109. {
  110. CAcdCore::GetInstance().getQueueMgr().delAgent(pAgent, true); // 从排队队列中删除
  111. pAgent->release(0);
  112. delete pAgent;
  113. pAgent = NULL;
  114. }
  115. }
  116. m_AgentMap.RemoveAll();
  117. }
  118. /*****************************************************************
  119. **【函数名称】 insertAgent
  120. **【函数功能】 座席状态变化的对应处理
  121. **【参数】 a_AgentID 座席工号
  122. a_ExtID 分机号
  123. a_GroupID 座席组号
  124. a_AgentType 座席类型
  125. a_TimeOverWork 话后处理时长
  126. a_ExtStatus 关联的分机状态
  127. **【返回值】
  128. ****************************************************************/
  129. BOOL CAgentOffice::insertAgent( UINT a_AgentID, UINT a_ExtID, LPCTSTR a_GroupID, UINT a_AgentType, UINT a_TimePostProcessing, INNER_STATE a_ExtStatus )
  130. {
  131. CSingleLock Lock(&m_Cs4AgentMap, TRUE);
  132. // 查找是否存在当前座席
  133. if(isAgentExisted(a_AgentID))
  134. return FALSE;
  135. // 保存对象
  136. CAgent* pAgent = new CAgent(a_AgentID, a_ExtID, a_GroupID, a_AgentType, a_TimePostProcessing);
  137. m_AgentMap.SetAt(pAgent->id(), pAgent); // 座席添加到全体座席索引
  138. CAcdCore::GetInstance().getQueueMgr().addAgent(pAgent);
  139. pAgent->onAssoExtStatusUpdated(a_ExtStatus);// 设置座席当前状态
  140. return TRUE;
  141. }
  142. /*****************************************************************
  143. **【函数名称】 isAgentExisted
  144. **【函数功能】 指定工号的座席是否存在
  145. **【参数】 a_AgentId: 要查找的座席工号
  146. **【返回值】
  147. ****************************************************************/
  148. BOOL CAgentOffice::isAgentExisted( UINT a_AgentId )
  149. {
  150. return getAgentById(a_AgentId) == NULL ? FALSE : TRUE;
  151. }
  152. /*****************************************************************
  153. **【函数名称】 isAgentExisted
  154. **【函数功能】 指定工号及IP的座席是否存在
  155. **【参数】 a_AgentId: 要查找的座席工号
  156. a_AgentIp: 要查找的座席IP
  157. **【返回值】
  158. ****************************************************************/
  159. BOOL CAgentOffice::isAgentExisted( UINT a_AgentId, const CString& a_AgentIp )
  160. {
  161. return getAgentByIp(a_AgentId, a_AgentIp) == NULL ? FALSE : TRUE;
  162. }
  163. /*****************************************************************
  164. **【函数名称】 removeAgent
  165. **【函数功能】 删除指定座席
  166. **【参数】 a_AgentID: 座席工号
  167. a_HostAgent: 主控制坐席工号
  168. **【返回值】
  169. ****************************************************************/
  170. BOOL CAgentOffice::removeAgent( UINT a_AgentID, UINT a_HostAgent )
  171. {
  172. CAgent* pAgent = NULL;
  173. CSingleLock Lock(&m_Cs4AgentMap, TRUE);
  174. if(m_AgentMap.Lookup(a_AgentID, pAgent))
  175. {
  176. CAcdCore::GetInstance().getQueueMgr().delAgent(pAgent);
  177. m_AgentMap.RemoveKey(a_AgentID); // 从全体座席索引中删除
  178. pAgent->release(a_HostAgent);
  179. delete pAgent;
  180. pAgent = NULL;
  181. return TRUE;
  182. }
  183. return FALSE;
  184. }
  185. /*****************************************************************
  186. **【函数名称】 getAgentAssoExten
  187. **【函数功能】 查找座席对应的分机号
  188. **【参数】 a_AgentID: 座席工号
  189. **【返回值】 该座席关联的分机号
  190. ****************************************************************/
  191. UINT CAgentOffice::getAgentAssoExten( UINT a_AgentID )
  192. {
  193. CAgent* pAgent = getAgentById(a_AgentID);
  194. return pAgent == NULL ? 0 : pAgent->assoExten();
  195. }
  196. /*****************************************************************
  197. **【函数名称】 getAgentGroup
  198. **【函数功能】 查找座席对应的类型
  199. **【参数】 a_AgentID: 座席工号
  200. **【返回值】 该座席关联的类型
  201. ****************************************************************/
  202. UINT CAgentOffice::getAgentType( UINT a_AgentID )
  203. {
  204. CAgent* pAgent = getAgentById(a_AgentID);
  205. return pAgent == NULL ? 0 : pAgent->type();
  206. }
  207. /*****************************************************************
  208. **【函数名称】 getAgentState
  209. **【函数功能】 查找指定座席的当前状态
  210. **【参数】 a_AgentID: 座席工号
  211. **【返回值】 该座席当前状态
  212. ****************************************************************/
  213. UINT CAgentOffice::getAgentState( UINT a_AgentID )
  214. {
  215. CAgent* pAgent = getAgentById(a_AgentID);
  216. return pAgent == NULL ? AGENT_STATE_UNKNOWN : pAgent->state();
  217. }
  218. /*****************************************************************
  219. **【函数名称】 isAgentRepose
  220. **【函数功能】 查找指定座席是否是置忙状态
  221. **【参数】 a_AgentID: 座席工号
  222. **【返回值】
  223. ****************************************************************/
  224. BOOL CAgentOffice::isAgentRepose( UINT a_AgentID )
  225. {
  226. CAgent* pAgent = getAgentById(a_AgentID);
  227. return pAgent == NULL ? FALSE : pAgent->isRepose();
  228. }
  229. /*****************************************************************
  230. **【函数名称】 lockAgent
  231. **【函数功能】 临时对座席进行锁定
  232. **【参数】 a_AgentId: 座席工号
  233. **【返回值】
  234. ****************************************************************/
  235. BOOL CAgentOffice::lockAgent( UINT a_AgentId )
  236. {
  237. CAgent* pAgent = getAgentById(a_AgentId);
  238. if(pAgent != NULL)
  239. return pAgent->lock();
  240. else
  241. return FALSE;
  242. }
  243. /*****************************************************************
  244. **【函数名称】 setAgentState4Calling
  245. **【函数功能】 为外呼设置座席状态
  246. **【参数】 a_AgentId: 座席工号
  247. **【返回值】
  248. ****************************************************************/
  249. BOOL CAgentOffice::setAgentState4Calling(UINT a_AgentId)
  250. {
  251. CAgent* pAgent = getAgentById(a_AgentId);
  252. ASSERT(pAgent != NULL);
  253. if (pAgent == NULL)
  254. return FALSE;
  255. // 确保一下座席状态空闲
  256. // ych 2018.7.11
  257. //if (!pAgent->setState(AGENT_STATE_FREE))
  258. if(!pAgent->setFreeForAgentCall())
  259. return FALSE;
  260. return pAgent->lockForCall();
  261. //return pAgent->lock();
  262. }
  263. /*****************************************************************
  264. **【函数名称】 onExtenStateUpdated
  265. **【函数功能】 分机状态变化事件响应
  266. **【参数】 a_pCmd: PDU命令内容
  267. **【返回值】
  268. ****************************************************************/
  269. void CAgentOffice::onExtenStateUpdated( UINT a_AgentID, CPduEntity* a_pCmd )
  270. {
  271. CAgent* pAgent = getAgentByExt(a_AgentID, a_pCmd->GetDataUInt(0));
  272. if(pAgent != NULL)
  273. pAgent->onAssoExtStatusUpdated((INNER_STATE)a_pCmd->GetDataUInt(1), a_pCmd);
  274. }
  275. /*****************************************************************
  276. **【函数名称】 setAgentState
  277. **【函数功能】 设置指定座席的逻辑状态
  278. **【参数】 a_AgentId: 座席工号
  279. a_AgentState: 座席状态
  280. **【返回值】
  281. ****************************************************************/
  282. BOOL CAgentOffice::setAgentState( UINT a_AgentID, AGENT_STATE a_AgentStatus )
  283. {
  284. CAgent* pAgent = getAgentById(a_AgentID);
  285. ASSERT(pAgent != NULL);
  286. if(pAgent != NULL)
  287. return pAgent->setState(a_AgentStatus);
  288. else
  289. return FALSE;
  290. }
  291. BOOL CAgentOffice::setAgentState(UINT a_AgentID, AGENT_STATE a_AgentStatus, bool forceLogout)
  292. {
  293. CAgent* pAgent = getAgentById(a_AgentID);
  294. ASSERT(pAgent != NULL);
  295. if (pAgent != NULL)
  296. return pAgent->setState(a_AgentStatus, forceLogout);
  297. else
  298. return FALSE;
  299. }
  300. /*****************************************************************
  301. **【函数名称】 isNoAgent
  302. **【函数功能】 是否无座席签入
  303. **【参数】
  304. **【返回值】
  305. ****************************************************************/
  306. BOOL CAgentOffice::isNoAgent( void )
  307. {
  308. return (m_AgentMap.GetCount() == 0) ? TRUE : FALSE;
  309. }
  310. /*****************************************************************
  311. **【函数名称】 getStateSpecAgentList
  312. **【函数功能】 获取指定状态的座席列表
  313. **【参数】 SpecState: 指定状态
  314. **【返回值】 座席工号字符串列表,以 | 进行分隔
  315. ****************************************************************/
  316. void CAgentOffice::getStateSpecAgentList( AGENT_LIST_SPEC_STATE SpecState, CString& AgentList )
  317. {
  318. AgentList = _T("");
  319. CSingleLock Lock(&m_Cs4AgentMap, TRUE);
  320. UINT Key;
  321. CAgent* pAgent;
  322. POSITION pos = m_AgentMap.GetStartPosition();
  323. while(pos != NULL)
  324. {
  325. bool IsInsert = false;
  326. m_AgentMap.GetNextAssoc(pos, Key, pAgent);
  327. ASSERT(pAgent != NULL);
  328. switch(SpecState)
  329. {
  330. case AGENT_LIST_FREE: // 空闲座席列表
  331. if(pAgent->state() == AGENT_STATE_FREE)
  332. IsInsert = true;
  333. break;
  334. case AGENT_LIST_BUSY: // 忙
  335. if(pAgent->state() != AGENT_STATE_FREE && pAgent->state() != AGENT_STATE_LOGOUT)
  336. IsInsert = true;
  337. break;
  338. case AGENT_LIST_TALKING: // 通话
  339. if(pAgent->state() == AGENT_STATE_BUSY)
  340. IsInsert = true;
  341. break;
  342. case AGENT_LIST_ALTERING: // 来电振铃
  343. if(CAcdCore::GetInstance().getExtenCtrl().getExtenState(pAgent->assoExten()) == INNER_STATE_ALERTING)
  344. IsInsert = true;
  345. break;
  346. } // end switch
  347. // 如果是指定状态的座席
  348. if(IsInsert)
  349. {
  350. CString block;
  351. block.Format(_T("%lu,%lu"), pAgent->id(), pAgent->assoExten());
  352. if(AgentList.GetLength() != 0)
  353. AgentList += _T("|");
  354. AgentList += block;
  355. } // end if
  356. } // end while
  357. }
  358. void CAgentOffice::GetCurAgentCount(int & AgentSpeakCount, int & AgentOnlineCount, int & AgentReposeCount)
  359. {
  360. CSingleLock Lock(&m_Cs4AgentMap, TRUE);
  361. UINT Key;
  362. CAgent* pAgent = NULL;
  363. POSITION pos = m_AgentMap.GetStartPosition();
  364. while (pos != NULL)
  365. {
  366. m_AgentMap.GetNextAssoc(pos, Key, pAgent);
  367. if (pAgent != NULL)
  368. {
  369. switch (pAgent->state())
  370. {
  371. case AGENT_STATE_REPOSE: // 小休
  372. AgentReposeCount++;
  373. break;
  374. case AGENT_STATE_BUSY: // 通话中
  375. AgentSpeakCount++;
  376. break;
  377. } // end switch
  378. }
  379. } // end while
  380. AgentOnlineCount = m_AgentMap.GetCount() - AgentReposeCount;
  381. }
  382. void CAgentOffice::GetCurAgentCount(int & AgentSpeakCount, int & AgentOnlineCount, int & AgentReposeCount, int & AgentFreeCount, int &AgentProcessingCount, int &AgentRingCount)
  383. {
  384. AgentSpeakCount = 0;
  385. AgentOnlineCount = 0;
  386. AgentReposeCount = 0;
  387. AgentFreeCount = 0;
  388. AgentProcessingCount = 0;
  389. AgentRingCount = 0;
  390. CSingleLock Lock(&m_Cs4AgentMap, TRUE);
  391. UINT Key;
  392. CAgent* pAgent = NULL;
  393. POSITION pos = m_AgentMap.GetStartPosition();
  394. while (pos != NULL)
  395. {
  396. m_AgentMap.GetNextAssoc(pos, Key, pAgent);
  397. if (pAgent != NULL)
  398. {
  399. switch (pAgent->state())
  400. {
  401. case AGENT_STATE_FREE: // 空闲
  402. AgentFreeCount++;
  403. break;
  404. case AGENT_STATE_REPOSE: // 小休
  405. AgentReposeCount++;
  406. break;
  407. case AGENT_STATE_BUSY: // 通话中
  408. AgentSpeakCount++;
  409. break;
  410. case AGENT_STATE_POST_PROCESSING: // 话后处理
  411. AgentProcessingCount++;
  412. break;
  413. case AGENT_STATE_REQUESTED: // 被请求/振铃
  414. AgentRingCount++;
  415. break;
  416. } // end switch
  417. }
  418. } // end while
  419. AgentOnlineCount = m_AgentMap.GetCount();
  420. }
  421. void CAgentOffice::getAllAgentStateList(CString & AgentList)
  422. {
  423. CSingleLock Lock(&m_Cs4AgentMap, TRUE);
  424. UINT Key;
  425. CAgent* pAgent = NULL;
  426. CString agent;
  427. POSITION pos = m_AgentMap.GetStartPosition();
  428. while (pos != NULL)
  429. {
  430. m_AgentMap.GetNextAssoc(pos, Key, pAgent);
  431. if (pAgent)
  432. {
  433. agent.Format("%d,%d,%d,%s|", pAgent->id(), pAgent->assoExten(), pAgent->state(), pAgent->group());
  434. AgentList += agent;
  435. }
  436. }
  437. }
  438. std::vector<int> CAgentOffice::getAgentIDAll()
  439. {
  440. UINT id = 0;
  441. CAgent* agent = NULL;
  442. std::vector<int> VecInt;
  443. POSITION pos = m_AgentMap.GetStartPosition();
  444. while (pos)
  445. {
  446. m_AgentMap.GetNextAssoc(pos, id, agent);
  447. int AgentID = agent->id();
  448. VecInt.push_back(AgentID);
  449. }
  450. return VecInt;
  451. }
  452. std::map<UINT, CAgentProperty>& CAgentOffice::GetAgentPropertyMap()
  453. {
  454. return m_AgentPropertyMap;
  455. }