华辉中间件项目(代码服务器上没有,用杨成电脑的源代码上传的)

Queue.cpp 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #include "StdAfx.h"
  2. #include "Queue.h"
  3. #include "IncomingCall.h"
  4. #include "AcdCore.h"
  5. #include "StrategyLoop.h"
  6. #include "StrategyMaxFree.h"
  7. #include "StrategyMinAnswer.h"
  8. #include "StrategySpecifiedAgent.h"
  9. CQueue::CQueue(UINT QueueNo) : m_QueueNo(QueueNo)
  10. {
  11. __initStrategy();
  12. }
  13. CQueue::~CQueue( void )
  14. {
  15. __freeStrategy();
  16. }
  17. /*****************************************************************
  18. **【函数名称】 __initStrategy
  19. **【函数功能】 初始化座席分配策略
  20. **【参数】
  21. **【返回值】
  22. ****************************************************************/
  23. void CQueue::__initStrategy( void )
  24. {
  25. CStrategyAD* pStrategy = NULL;
  26. // 循环接听
  27. pStrategy = new CStrategyLoop();
  28. m_StrategyMap.SetAt(AGENT_STRATEGY_LOOP, pStrategy);
  29. // 目前空闲时间最长的座席
  30. pStrategy = new CStrategyMaxFree();
  31. m_StrategyMap.SetAt(AGENT_STRATEGY_MAX_CUR_FREE_TIME, pStrategy);
  32. // 目前接听次数最少的坐席
  33. pStrategy = new CStrategyMinAnswer();
  34. m_StrategyMap.SetAt(AGENT_STRATEGY_MINI_CALLS, pStrategy);
  35. // 指定座席
  36. pStrategy = new CStrategySpecifiedAgent();
  37. m_StrategyMap.SetAt(AGENT_STRATEGY_KNOWN, pStrategy);
  38. }
  39. /*****************************************************************
  40. **【函数名称】 __freeStrategy
  41. **【函数功能】 释放座席分配策略
  42. **【参数】
  43. **【返回值】
  44. ****************************************************************/
  45. void CQueue::__freeStrategy( void )
  46. {
  47. AGENT_STRATEGY Key;
  48. CStrategyAD* pStrategy = NULL;
  49. POSITION Pos = m_StrategyMap.GetStartPosition();
  50. while(Pos != NULL)
  51. {
  52. m_StrategyMap.GetNextAssoc(Pos, Key, pStrategy);
  53. ASSERT(pStrategy != NULL);
  54. delete pStrategy;
  55. }
  56. m_StrategyMap.RemoveAll();
  57. }
  58. /*****************************************************************
  59. **【函数名称】 __getStrategy
  60. **【函数功能】 获取指定的座席分配策略
  61. **【参数】
  62. **【返回值】
  63. ****************************************************************/
  64. CStrategyAD* CQueue::__getStrategy( AGENT_STRATEGY StrategyId )
  65. {
  66. // 找到对应的座席分配策略
  67. CStrategyAD* pStrategy = NULL;
  68. if(!m_StrategyMap.Lookup(StrategyId, pStrategy))
  69. pStrategy = m_StrategyMap[AGENT_STRATEGY_LOOP]; // 如果指定的策略不存在,则选取循环接听策略
  70. return pStrategy;
  71. }
  72. /*****************************************************************
  73. **【函数名称】 __onAgentDispatched
  74. **【函数功能】 处理请求座席结果
  75. **【参数】 Result: 请求座席结果
  76. Agent: 请求到的座席ID
  77. Exten: 请求到的座席分机号
  78. CallIndex: 请求座席的来电索引
  79. **【返回值】
  80. ****************************************************************/
  81. void CQueue::__onAgentDispatched( QUEUE_AGENT_RESULT Result, UINT Agent, UINT Exten, CIncomingCall* pCall )
  82. {
  83. switch(Result)
  84. {
  85. case QUEUE_AGENT_OK: // 请求座席成功
  86. {
  87. pCall->onQueueOK(Agent, Exten);
  88. m_CallGroup.delCall(pCall->index());
  89. }
  90. break;
  91. case QUEUE_AGENT_FAILED_NO_AGENT: // 无签入座席
  92. case QUEUE_AGENT_FAILED_NO_FREE: // 座席全忙
  93. case QUEUE_AGETN_FAILED_NO_SPEC: // 在指定策略下无匹配座席
  94. {
  95. pCall->onQueueFailed(Result, Agent);
  96. }
  97. break;
  98. } // end switch
  99. }
  100. /*****************************************************************
  101. **【函数名称】 clear
  102. **【函数功能】 清除所有资源
  103. **【参数】
  104. **【返回值】
  105. ****************************************************************/
  106. void CQueue::clear( void )
  107. {
  108. m_CallGroup.clear();
  109. m_AgentGroup.clear();
  110. }
  111. /*****************************************************************
  112. **【函数名称】 onQueueRequest
  113. **【函数功能】 呼叫请求排队响应
  114. **【参数】 pCmd: PDU命令内容
  115. **【返回值】 被操作呼叫
  116. ****************************************************************/
  117. void CQueue::onQueueRequest( CPduEntity* pCmd )
  118. {
  119. int CallPos = 0;
  120. // 是否为重复请求座席
  121. CIncomingCall* pCall = m_CallGroup.getCall(pCmd->GetDataInt(1));
  122. if(pCall != NULL)
  123. {
  124. pCall->updateQueueInfo(pCmd); // 重置座席分配策略及信息
  125. }
  126. else
  127. {
  128. pCall = m_CallGroup.addCall(pCmd, CallPos);
  129. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, "{CQueue}: 呼叫请求排队, m_QueueNo=%d,Index = %d,Caller=%s", m_QueueNo, CallPos, pCmd->GetDataString(6));
  130. } // end if
  131. // 当前来电是否可以请求座席(如果不能,直接返回请求座席失败)
  132. if(pCall != m_CallGroup.getTopWaitedCall())
  133. {
  134. QUEUE_AGENT_RESULT Result = QUEUE_AGENT_FAILED_NO_FREE;
  135. if(m_AgentGroup.GetCount() == 0)
  136. Result = QUEUE_AGENT_FAILED_NO_AGENT;
  137. __onAgentDispatched(Result, CallPos, 0, pCall);
  138. } // end if
  139. else
  140. {
  141. // 处理排队请求
  142. distributeAgent();
  143. }
  144. }
  145. /*****************************************************************
  146. **【函数名称】 onQueueCancel
  147. **【函数功能】 呼叫取消排队
  148. **【参数】 pCmd: PDU命令内容
  149. **【返回值】
  150. ****************************************************************/
  151. bool CQueue::onQueueCancel( CPduEntity* pCmd )
  152. {
  153. // 删除呼叫
  154. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, "{CQueue}: 呼叫取消排队, m_QueueNo=%d,Index = %d,Caller=%s", m_QueueNo, pCmd->GetDataInt(1), pCmd->GetDataString(6));
  155. return m_CallGroup.delCall(pCmd->GetDataInt(1));
  156. }
  157. /*****************************************************************
  158. **【函数名称】 onQueuePause
  159. **【函数功能】 呼叫暂停排队
  160. **【参数】 pCmd: PDU命令内容
  161. **【返回值】
  162. ****************************************************************/
  163. bool CQueue::onQueuePause( CPduEntity* pCmd )
  164. {
  165. CIncomingCall* pCall = m_CallGroup.getCall(pCmd->GetDataInt(0));
  166. if(pCall == NULL)
  167. return false;
  168. pCall->setCallState(OUTER_CALL_PAUSE);
  169. return true;
  170. }
  171. /*****************************************************************
  172. **【函数名称】 onQueueContinue
  173. **【函数功能】 呼叫继续排队
  174. **【参数】 pCmd: PDU命令内容
  175. **【返回值】
  176. ****************************************************************/
  177. bool CQueue::onQueueContinue( CPduEntity* pCmd )
  178. {
  179. CIncomingCall* pCall = m_CallGroup.getCall(pCmd->GetDataInt(1));
  180. if(pCall == NULL)
  181. return false;
  182. pCall->updateQueueInfo(pCmd);
  183. // 主动请求坐席
  184. distributeAgent();
  185. return true;
  186. }
  187. /*****************************************************************
  188. **【函数名称】 addAgent
  189. **【函数功能】 添加座席
  190. **【参数】
  191. **【返回值】
  192. ****************************************************************/
  193. void CQueue::addAgent( CAgent* pAgent )
  194. {
  195. m_AgentGroup.add(pAgent);
  196. }
  197. /*****************************************************************
  198. **【函数名称】 delAgent
  199. **【函数功能】 删除座席
  200. **【参数】
  201. **【返回值】
  202. ****************************************************************/
  203. void CQueue::delAgent( CAgent* pAgent )
  204. {
  205. m_AgentGroup.remove(pAgent);
  206. }
  207. /*****************************************************************
  208. **【函数名称】 distributeAgent
  209. **【函数功能】
  210. **【参数】
  211. **【返回值】
  212. ****************************************************************/
  213. void CQueue::distributeAgent( void )
  214. {
  215. // 查找当前要排队的呼叫
  216. CIncomingCall* pCall = m_CallGroup.getTopWaitedCall();
  217. if(pCall == NULL)
  218. return;
  219. pCall->setCallState(OUTER_CALL_QUEUE);
  220. CStrategyAD* pStrategy = __getStrategy(pCall->agentStrategy()); // 请求座席的排队策略
  221. ASSERT(pStrategy != NULL);
  222. // 显示日志
  223. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{坐席排队策略号: %lu"), pCall->agentStrategy());
  224. // 开始请求座席
  225. UINT Agent = 0; // 要返回的座席工号
  226. UINT Exten = 0; // 要返回的座席分机号
  227. QUEUE_AGENT_RESULT Result = m_AgentGroup.distributeAgent(pStrategy, pCall->infoEx(), Agent, Exten);
  228. // 处理请求结果
  229. __onAgentDispatched(Result, Agent, Exten, pCall);
  230. }