中间件底层,websocket

QueueMgr.cpp 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. #include "StdAfx.h"
  2. #include "QueueMgr.h"
  3. #include "Queue.h"
  4. #include "AgentOffice.h"
  5. #include "IncomingCall.h"
  6. #include "Agent.h"
  7. #include <map>
  8. CQueueMgr::CQueueMgr(void)
  9. {
  10. }
  11. CQueueMgr::~CQueueMgr(void)
  12. {
  13. __freeQueues();
  14. }
  15. /*****************************************************************
  16. **【函数名称】 __getQueue
  17. **【函数功能】 获取指定来电队列
  18. **【参数】
  19. **【返回值】
  20. ****************************************************************/
  21. CQueue* CQueueMgr::__getQueue(UINT QueueNo, bool NewWhenNull /*= false*/ )
  22. {
  23. for(int i = 0; i < m_QueueArray.GetCount(); ++i)
  24. {
  25. CQueue* pQueue = m_QueueArray[i];
  26. ASSERT(pQueue != NULL);
  27. if(pQueue->no() == QueueNo)
  28. return pQueue;
  29. }
  30. if(NewWhenNull)
  31. {
  32. CQueue* pQueue = new CQueue(QueueNo);
  33. m_QueueArray.Add(pQueue);
  34. return pQueue;
  35. }
  36. return NULL;
  37. }
  38. /*****************************************************************
  39. **【函数名称】 __freeQueues
  40. **【函数功能】 释放所有来电队列
  41. **【参数】
  42. **【返回值】
  43. ****************************************************************/
  44. void CQueueMgr::__freeQueues( void )
  45. {
  46. for(int i = 0; i < m_QueueArray.GetCount(); ++i)
  47. {
  48. CQueue* pQueue = m_QueueArray[i];
  49. ASSERT(pQueue != NULL);
  50. pQueue->clear();
  51. delete pQueue;
  52. pQueue = NULL;
  53. }
  54. m_QueueArray.RemoveAll();
  55. }
  56. /*****************************************************************
  57. **【函数名称】 onQueueAsking
  58. **【函数功能】 IVR请求座席命令响应
  59. **【参数】 pCmd: PDU命令内容
  60. pAgentOffice: 关联的座席管理类
  61. **【返回值】
  62. ****************************************************************/
  63. void CQueueMgr::onQueueAsking( CPduEntity* pCmd )
  64. {
  65. UINT QueueNo = pCmd->GetDataUInt(4);
  66. CQueue* pQueue = __getQueue(QueueNo, true);
  67. ASSERT(pQueue != NULL);
  68. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, "{CQueueMgr}: 来电请求排队, Index = %d, CallID = %lu, Group = %lu, VipLevel = %d, CallerNum = %s",
  69. pCmd->GetDataInt(1),
  70. pCmd->GetDataULong(2),
  71. QueueNo,
  72. pCmd->GetDataInt(5),
  73. pCmd->GetDataString(6));
  74. pQueue->onQueueRequest(pCmd);
  75. }
  76. /*****************************************************************
  77. **【函数名称】 onQueueCancel
  78. **【函数功能】 IVR继续请求排队命令响应
  79. **【参数】 pCmd: PDU命令内容
  80. pAgentOffice: 关联的座席管理类
  81. **【返回值】
  82. ****************************************************************/
  83. void CQueueMgr::onQueueCancel( CPduEntity* pCmd )
  84. {
  85. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, "{CQueueMgr}: 来电取消排队, Index = %d, CallId = %lu",
  86. pCmd->GetDataInt(1),
  87. pCmd->GetDataULong(2));
  88. for(int i = 0; i < m_QueueArray.GetCount(); ++i)
  89. {
  90. if(m_QueueArray[i]->onQueueCancel(pCmd))
  91. return;
  92. }
  93. }
  94. /*****************************************************************
  95. **【函数名称】 onQueueContinue
  96. **【函数功能】 IVR继续请求排队命令响应
  97. **【参数】 pCmd: 命令内容
  98. pAgentOffice: 关联的座席管理类
  99. **【返回值】
  100. ****************************************************************/
  101. void CQueueMgr::onQueueContinue( CPduEntity* pCmd )
  102. {
  103. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, "{CQueueMgr}: 来电继续排队, Index = %d, CallId = %lu, CallerNum = %s",
  104. pCmd->GetDataInt(1),
  105. pCmd->GetDataULong(2),
  106. pCmd->GetDataString(4));
  107. for(int i = 0; i < m_QueueArray.GetCount(); ++i)
  108. {
  109. if(m_QueueArray[i]->onQueueContinue(pCmd))
  110. return;
  111. }
  112. }
  113. /*****************************************************************
  114. **【函数名称】 onQueuePause
  115. **【函数功能】 IVR暂停排队命令响应
  116. **【参数】 pCmd: PDU命令内容
  117. pAgentOffice: 关联的座席管理类
  118. **【返回值】
  119. ****************************************************************/
  120. void CQueueMgr::onQueuePause( CPduEntity* pCmd )
  121. {
  122. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, "{Queue}: 来电暂停排队, Index = %d", pCmd->GetDataInt(0));
  123. for(int i = 0; i < m_QueueArray.GetCount(); ++i)
  124. {
  125. if(m_QueueArray[i]->onQueuePause(pCmd))
  126. return;
  127. }
  128. }
  129. void CQueueMgr::onUpdateCallIndex()
  130. {
  131. CString callIndex;
  132. for (int i = 0; i < m_QueueArray.GetCount(); ++i)
  133. {
  134. auto pQueue = m_QueueArray[i];
  135. callIndex += pQueue->callIndex();
  136. }
  137. pushCallIndex(callIndex.GetBuffer(0));
  138. callIndex.ReleaseBuffer();
  139. }
  140. bool CQueueMgr::GetFreeAgent(int GroupNo, UINT& AgentId, UINT& ExtenId)
  141. {
  142. CQueue* pQueue = __getQueue(GroupNo);
  143. if (pQueue)
  144. {
  145. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "[%s][%d]", __FUNCTION__, __LINE__);
  146. CAgent *pAgent = pQueue->GetFreeAgentForLoop();
  147. if (pAgent != NULL)
  148. {
  149. AgentId = pAgent->id();
  150. ExtenId = pAgent->assoExten();
  151. return true;
  152. }
  153. }
  154. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "[%s][%d]", __FUNCTION__, __LINE__);
  155. return false;
  156. }
  157. /*****************************************************************
  158. **【函数名称】 callCount
  159. **【函数功能】 读取等待排队的来电数量
  160. **【参数】
  161. **【返回值】
  162. ****************************************************************/
  163. UINT CQueueMgr::callCount( void )
  164. {
  165. UINT Count = 0;
  166. for(int i = 0; i < m_QueueArray.GetCount(); ++i)
  167. {
  168. Count += m_QueueArray[i]->callCount();
  169. }
  170. return Count;
  171. }
  172. /*****************************************************************
  173. **【函数名称】 callCount
  174. **【函数功能】 读取等待排队的来电数量
  175. **【参数】
  176. **【返回值】
  177. ****************************************************************/
  178. UINT CQueueMgr::callCount( UINT QueueNo )
  179. {
  180. CQueue* pQueue = __getQueue(QueueNo);
  181. if(pQueue != NULL)
  182. return pQueue->callCount();
  183. else
  184. return 0;
  185. }
  186. CString CQueueMgr::waitCount()
  187. {
  188. CString str;
  189. // 2022-09-02 利用 m_queryCount去重
  190. m_QueryCount.clear();
  191. for (int i = 0; i < m_QueueArray.GetCount(); ++i)
  192. {
  193. m_QueryCount[m_QueueArray[i]->no()] = m_QueueArray[i]->callCount();
  194. }
  195. std::stringstream ss;
  196. auto it = m_QueryCount.begin();
  197. while (it != m_QueryCount.end())
  198. {
  199. ss << it->first << "|" << it->second << "#";
  200. ++it;
  201. }
  202. str.Format("%s", ss.str().c_str());
  203. return str;
  204. }
  205. UINT CQueueMgr::talkIngCount(UINT QueueNo)
  206. {
  207. CQueue* pQueue = __getQueue(QueueNo);
  208. if (pQueue != NULL)
  209. return pQueue->talkIngAgentCount();
  210. else
  211. return 0;
  212. }
  213. /*****************************************************************
  214. **【函数名称】 clear
  215. **【函数功能】 释放资源
  216. **【参数】
  217. **【返回值】
  218. ****************************************************************/
  219. void CQueueMgr::clear( void )
  220. {
  221. __freeQueues();
  222. }
  223. /*****************************************************************
  224. **【函数名称】 getCallInfo
  225. **【函数功能】 获取指定呼叫的相关信息用于UI展现
  226. **【参数】
  227. **【返回值】
  228. ****************************************************************/
  229. bool CQueueMgr::getCallInfo( Call2Show& Info )
  230. {
  231. for(int i = 0; i < m_QueueArray.GetCount(); ++i)
  232. {
  233. if(m_QueueArray[i]->getCallInfo(Info))
  234. return true;
  235. }
  236. return false;
  237. }
  238. /*****************************************************************
  239. **【函数名称】 addAgent
  240. **【函数功能】 添加座席
  241. **【参数】
  242. **【返回值】
  243. ****************************************************************/
  244. void CQueueMgr::addAgent( CAgent* pAgent )
  245. {
  246. ASSERT(pAgent != NULL);
  247. UINT GroupNo = 0;
  248. TCHAR AgentGroup[AGENT_GROUP_BUF_LEN] = { 0 };
  249. lstrcpy(AgentGroup, pAgent->group());
  250. AgentGroupNoList& GrouNoList = pAgent->groupNoList();
  251. TCHAR* lpNext = NULL;
  252. TCHAR* lpToken = strtok_s(AgentGroup, AGENT_GROUP_SPLIT_FLAG, &lpNext);
  253. while(lpToken != NULL)
  254. {
  255. sscanf_s(lpToken, "%u", &GroupNo);
  256. CQueue* pQueue = __getQueue(GroupNo, true);
  257. ASSERT(pQueue != NULL);
  258. GrouNoList.AddTail(GroupNo);
  259. pQueue->addAgent(pAgent);
  260. lpToken = strtok_s(NULL, AGENT_GROUP_SPLIT_FLAG, &lpNext);
  261. }
  262. }
  263. /*****************************************************************
  264. **【函数名称】 delAgent
  265. **【函数功能】 删除座席
  266. **【参数】
  267. **【返回值】
  268. ****************************************************************/
  269. void CQueueMgr::delAgent( CAgent* pAgent, bool isClear)
  270. {
  271. AgentGroupNoList& GrouNoList = pAgent->groupNoList();
  272. POSITION Pos = GrouNoList.GetHeadPosition();
  273. while(Pos != NULL)
  274. {
  275. UINT GroupNo = GrouNoList.GetNext(Pos);
  276. CQueue* pQueue = __getQueue(GroupNo);
  277. if(pQueue != NULL)
  278. pQueue->delAgent(pAgent,!isClear); // 2022-09-13 如果isclear是真,是cti断开造成,就传递false,不保存更新在线坐席信息
  279. }
  280. }
  281. /*****************************************************************
  282. **【函数名称】 onAgentFree
  283. **【函数功能】 座席的处理函数
  284. **【参数】
  285. **【返回值】
  286. ****************************************************************/
  287. void CQueueMgr::onAgentFree( CAgent* pAgent )
  288. {
  289. CQueue* pQueueDst = NULL;
  290. UINT CallCountMax = 0;
  291. AgentGroupNoList& GrouNoList = pAgent->groupNoList();
  292. // 查找排队呼叫最多的队列
  293. POSITION Pos = GrouNoList.GetHeadPosition();
  294. while(Pos != NULL)
  295. {
  296. UINT GroupNo = GrouNoList.GetNext(Pos);
  297. CQueue* pQueue = __getQueue(GroupNo);
  298. ASSERT(pQueue != NULL);
  299. UINT CallCout = pQueue->callCount();
  300. if(CallCout > CallCountMax)
  301. {
  302. pQueueDst = pQueue;
  303. CallCountMax = CallCout;
  304. }
  305. }
  306. if(CallCountMax > 0)
  307. pQueueDst->distributeAgent();
  308. }