IncomingNotificationHandler.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. using CallCenter.Caches;
  2. using CallCenter.Calls;
  3. using CallCenter.Ivrs;
  4. using CallCenter.Devices;
  5. using CallCenter.Notifications;
  6. using CallCenter.Share.Enums;
  7. using MediatR;
  8. using Microsoft.Extensions.Options;
  9. using NewRock.Sdk;
  10. using NewRock.Sdk.Transfer.Connect.Request;
  11. using XF.Domain.Constants;
  12. using XF.Domain.Cache;
  13. using CallCenter.Settings;
  14. using Microsoft.Extensions.Logging;
  15. using NewRock.Sdk.Transfer.Queue.Request;
  16. namespace CallCenter.Application.Handlers
  17. {
  18. public class IncomingNotificationHandler : INotificationHandler<IncomingNotification>
  19. {
  20. private readonly ICallRepository _callRepository;
  21. private readonly ICallDetailRepository _callDetailRepository;
  22. private readonly ISystemSettingCacheManager _systemSettingCacheManager;
  23. //private readonly ITelCacheManager _telCacheManager;
  24. private readonly IIvrCacheManager _ivrCacheManager;
  25. private readonly INewRockClient _newRockClient;
  26. private readonly IOptionsSnapshot<DeviceConfigs> _options;
  27. private readonly ITypedCache<WorkTimeSettings> _worktimeCache;
  28. private readonly IOptionsSnapshot<WorkTimeSettings> _worktimeOptions;
  29. private readonly ILogger<IncomingNotificationHandler> _logger;
  30. private readonly ICallCacheManager _callCacheManager;
  31. public IncomingNotificationHandler(
  32. ICallRepository callRepository, ICallDetailRepository callDetailRepository,
  33. ISystemSettingCacheManager systemSettingCacheManager, IIvrCacheManager ivrCacheManager,
  34. INewRockClient newRockClient, IOptionsSnapshot<DeviceConfigs> options,
  35. ITypedCache<WorkTimeSettings> worktimeCache, IOptionsSnapshot<WorkTimeSettings> worktimeOptions,
  36. ILogger<IncomingNotificationHandler> logger, ICallCacheManager callCacheManager)
  37. {
  38. _callRepository = callRepository;
  39. _callDetailRepository = callDetailRepository;
  40. _systemSettingCacheManager = systemSettingCacheManager;
  41. _ivrCacheManager = ivrCacheManager;
  42. _newRockClient = newRockClient;
  43. _options = options;
  44. _worktimeCache = worktimeCache;
  45. _worktimeOptions = worktimeOptions;
  46. _logger = logger;
  47. _callCacheManager = callCacheManager;
  48. }
  49. public async Task Handle(IncomingNotification notification, CancellationToken cancellationToken)
  50. {
  51. var model = await _callRepository.GetAsync(
  52. x => x.ConversationId == notification.Visitor.Id && x.Trunk == notification.TrunkId &&
  53. x.FromNo == notification.Visitor.From && x.CreationTime >= DateTime.Now.AddHours(-2), cancellationToken);
  54. if (model != null)
  55. {
  56. model.CallStatus = ECallStatus.Incoming;
  57. await _callRepository.UpdateAsync(model, cancellationToken);
  58. var detail = new CallDetail()
  59. {
  60. CallId = model.Id,
  61. CallStatus = ECallStatus.Incoming,
  62. OMCallId = notification.Visitor.CallId,
  63. ConversationId = notification.Visitor.Id,
  64. EventName = notification.Attribute,
  65. FromNo = notification.Visitor.From,
  66. ToNo = notification.Visitor.To,
  67. };
  68. await _callDetailRepository.AddAsync(detail, cancellationToken);
  69. var correct = GetCorrectIvr(notification.Visitor.To);
  70. //TODO IVR处理
  71. var setting = _systemSettingCacheManager.GetSetting(SettingConstants.IVRConfig);
  72. if (bool.Parse(setting.SettingValue))
  73. {
  74. //TODO 获取工作或休息时间(接听策略)
  75. //var ivrList = _ivrCacheManager.GetIvrs();
  76. //var ivr = ivrList.First(x => x.IvrCategoryId == "08da9b9f-a35d-4ade-8ea7-55e8abbcdefd" && x.IsRoot);
  77. //var ivr = GetCorrectIvr();
  78. //_logger.LogInformation("transfer to ivr.no: {ivrNo}", ivr.No);
  79. //await _newRockClient.VisitorToMenu(
  80. // new VisitorToMenuRequest()
  81. // {
  82. // Attribute = "Connect",
  83. // Menu = new VisitorToMenuMenu() { Id = ivr.No },
  84. // Visitor = new VisitorToMenuVisitor() { Id = notification.Visitor.Id }
  85. // },
  86. // _options.Value.ReceiveKey, _options.Value.Expired, cancellationToken);
  87. switch (correct.eCorrectIvr)
  88. {
  89. //跳转IVR
  90. case ECorrectIvr.Ivr:
  91. var ivrList = _ivrCacheManager.GetIvrs();
  92. var ivr = ivrList.First(x => x.IvrCategoryId == correct.ReturnValue && x.IsRoot);
  93. _logger.LogInformation("transfer to ivr.no: {ivrNo}", ivr.No);
  94. await _newRockClient.VisitorToMenu(new VisitorToMenuRequest()
  95. {
  96. Attribute = "Connect",
  97. Menu = new VisitorToMenuMenu() { Id = ivr.No },
  98. Visitor = new VisitorToMenuVisitor() { Id = notification.Visitor.Id }
  99. },
  100. _options.Value.ReceiveKey, _options.Value.Expired, cancellationToken);
  101. model.InIvrTime = DateTime.Now;
  102. await _callRepository.UpdateAsync(model, cancellationToken);
  103. break;
  104. //直接转分机组
  105. case ECorrectIvr.Group:
  106. _logger.LogInformation("transfer to group.no:{groupNo}", correct.ReturnValue);
  107. await _newRockClient.VisitorToGroupQueue(new VisitorToGroupQueueRequest()
  108. {
  109. Attribute = "Queue",
  110. Visitor = new VisitorToGroupQueueVisitor() { Id = notification.Visitor.Id },
  111. Group = new VisitorToGroupQueueGroup() { Id = correct.ReturnValue }
  112. },
  113. _options.Value.ReceiveKey, _options.Value.Expired, cancellationToken);
  114. model.InGroupTime = DateTime.Now;
  115. await _callRepository.UpdateAsync(model, cancellationToken);
  116. //处理队列记录 TODO
  117. //_callCacheManager.AddCallCache(model);
  118. break;
  119. default:
  120. break;
  121. }
  122. }
  123. else
  124. {
  125. //TODO 跳转默认分机组
  126. }
  127. }
  128. }
  129. private Ivr GetCorrectIvr()
  130. {
  131. var worktimeSettings = _worktimeCache.GetOrAdd("worktimesettings", d => _worktimeOptions.Value, ExpireMode.Absolute, TimeSpan.FromDays(1));
  132. var categoryId = GetCorrectCategory(worktimeSettings);
  133. var ivrList = _ivrCacheManager.GetIvrs();
  134. var ivr = ivrList.First(x => x.IvrCategoryId == categoryId && x.IsRoot);
  135. return ivr;
  136. }
  137. private CorrectIvr GetCorrectIvr(string to)
  138. {
  139. var worktimeSettings = _worktimeCache.GetOrAdd("worktimesettings", d => _worktimeOptions.Value, ExpireMode.Absolute, TimeSpan.FromDays(1));
  140. var correct = GetCorrectCategory(worktimeSettings.LineSetting.First(x => x.NumNo == to));
  141. return correct;
  142. }
  143. private CorrectIvr GetCorrectCategory(LineSetting settings)
  144. {
  145. if (!settings.WorkDay.Contains((int)DateTime.Now.DayOfWeek))
  146. return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Group, ReturnValue = settings.RestToGroup };
  147. var time = TimeOnly.FromDateTime(DateTime.Now);
  148. if ((time >= TimeOnly.Parse(settings.MorningBegin) && time <= TimeOnly.Parse(settings.MorningEnd))
  149. || (time >= TimeOnly.Parse(settings.AfterBegin) && time <= TimeOnly.Parse(settings.AfterEnd)))
  150. {
  151. if (!string.IsNullOrEmpty(settings.WorkCategory))
  152. {
  153. return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Ivr, ReturnValue = settings.WorkCategory };
  154. }
  155. else
  156. {
  157. return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Group, ReturnValue = settings.WorkToGroup };
  158. }
  159. }
  160. else
  161. {
  162. if (!string.IsNullOrEmpty(settings.RestCategory))
  163. {
  164. return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Ivr, ReturnValue = settings.RestCategory };
  165. }
  166. else
  167. {
  168. return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Group,ReturnValue = settings.RestToGroup };
  169. }
  170. }
  171. }
  172. public class CorrectIvr
  173. {
  174. public string ReturnValue { get; set; }
  175. public ECorrectIvr eCorrectIvr { get; set; }
  176. }
  177. public enum ECorrectIvr
  178. {
  179. Ivr = 0,
  180. Group = 1,
  181. }
  182. private string GetCorrectCategory(WorkTimeSettings settings)
  183. {
  184. if (!settings.WorkDay.Contains((int)DateTime.Now.DayOfWeek))
  185. return settings.RestCategory;
  186. var time = TimeOnly.FromDateTime(DateTime.Now);
  187. if ((time >= TimeOnly.Parse(settings.MorningBegin) && time <= TimeOnly.Parse(settings.MorningEnd))
  188. || (time >= TimeOnly.Parse(settings.AfterBegin) && time <= TimeOnly.Parse(settings.AfterEnd))
  189. )
  190. return settings.WorkCategory;
  191. return settings.RestCategory;
  192. }
  193. }
  194. }