using CallCenter.Caches; using CallCenter.Calls; using CallCenter.Ivrs; using CallCenter.Devices; using CallCenter.Notifications; using CallCenter.Share.Enums; using MediatR; using Microsoft.Extensions.Options; using NewRock.Sdk; using NewRock.Sdk.Transfer.Connect.Request; using XF.Domain.Constants; using XF.Domain.Cache; using CallCenter.Settings; using Microsoft.Extensions.Logging; using NewRock.Sdk.Transfer.Queue.Request; namespace CallCenter.Application.Handlers { public class IncomingNotificationHandler : INotificationHandler { private readonly ICallRepository _callRepository; private readonly ICallDetailRepository _callDetailRepository; private readonly ISystemSettingCacheManager _systemSettingCacheManager; //private readonly ITelCacheManager _telCacheManager; private readonly IIvrCacheManager _ivrCacheManager; private readonly INewRockClient _newRockClient; private readonly IOptionsSnapshot _options; private readonly ITypedCache _worktimeCache; private readonly IOptionsSnapshot _worktimeOptions; private readonly ILogger _logger; private readonly ICallCacheManager _callCacheManager; public IncomingNotificationHandler( ICallRepository callRepository, ICallDetailRepository callDetailRepository, ISystemSettingCacheManager systemSettingCacheManager, IIvrCacheManager ivrCacheManager, INewRockClient newRockClient, IOptionsSnapshot options, ITypedCache worktimeCache, IOptionsSnapshot worktimeOptions, ILogger logger, ICallCacheManager callCacheManager) { _callRepository = callRepository; _callDetailRepository = callDetailRepository; _systemSettingCacheManager = systemSettingCacheManager; _ivrCacheManager = ivrCacheManager; _newRockClient = newRockClient; _options = options; _worktimeCache = worktimeCache; _worktimeOptions = worktimeOptions; _logger = logger; _callCacheManager = callCacheManager; } public async Task Handle(IncomingNotification notification, CancellationToken cancellationToken) { var model = await _callRepository.GetAsync( x => x.ConversationId == notification.Visitor.Id && x.Trunk == notification.TrunkId && x.FromNo == notification.Visitor.From && x.CreationTime >= DateTime.Now.AddHours(-2), cancellationToken); if (model != null) { model.CallStatus = ECallStatus.Incoming; await _callRepository.UpdateAsync(model, cancellationToken); var detail = new CallDetail() { CallId = model.Id, CallStatus = ECallStatus.Incoming, OMCallId = notification.Visitor.CallId, ConversationId = notification.Visitor.Id, EventName = notification.Attribute, FromNo = notification.Visitor.From, ToNo = notification.Visitor.To, }; await _callDetailRepository.AddAsync(detail, cancellationToken); var correct = GetCorrectIvr(notification.Visitor.To); //TODO IVR处理 var setting = _systemSettingCacheManager.GetSetting(SettingConstants.IVRConfig); if (bool.Parse(setting.SettingValue)) { //TODO 获取工作或休息时间(接听策略) //var ivrList = _ivrCacheManager.GetIvrs(); //var ivr = ivrList.First(x => x.IvrCategoryId == "08da9b9f-a35d-4ade-8ea7-55e8abbcdefd" && x.IsRoot); //var ivr = GetCorrectIvr(); //_logger.LogInformation("transfer to ivr.no: {ivrNo}", ivr.No); //await _newRockClient.VisitorToMenu( // new VisitorToMenuRequest() // { // Attribute = "Connect", // Menu = new VisitorToMenuMenu() { Id = ivr.No }, // Visitor = new VisitorToMenuVisitor() { Id = notification.Visitor.Id } // }, // _options.Value.ReceiveKey, _options.Value.Expired, cancellationToken); switch (correct.eCorrectIvr) { //跳转IVR case ECorrectIvr.Ivr: var ivrList = _ivrCacheManager.GetIvrs(); var ivr = ivrList.First(x => x.IvrCategoryId == correct.ReturnValue && x.IsRoot); _logger.LogInformation("transfer to ivr.no: {ivrNo}", ivr.No); await _newRockClient.VisitorToMenu(new VisitorToMenuRequest() { Attribute = "Connect", Menu = new VisitorToMenuMenu() { Id = ivr.No }, Visitor = new VisitorToMenuVisitor() { Id = notification.Visitor.Id } }, _options.Value.ReceiveKey, _options.Value.Expired, cancellationToken); model.InIvrTime = DateTime.Now; await _callRepository.UpdateAsync(model, cancellationToken); break; //直接转分机组 case ECorrectIvr.Group: _logger.LogInformation("transfer to group.no:{groupNo}", correct.ReturnValue); await _newRockClient.VisitorToGroupQueue(new VisitorToGroupQueueRequest() { Attribute = "Queue", Visitor = new VisitorToGroupQueueVisitor() { Id = notification.Visitor.Id }, Group = new VisitorToGroupQueueGroup() { Id = correct.ReturnValue } }, _options.Value.ReceiveKey, _options.Value.Expired, cancellationToken); model.InGroupTime = DateTime.Now; await _callRepository.UpdateAsync(model, cancellationToken); //处理队列记录 TODO //_callCacheManager.AddCallCache(model); break; default: break; } } else { //TODO 跳转默认分机组 } } } private Ivr GetCorrectIvr() { var worktimeSettings = _worktimeCache.GetOrAdd("worktimesettings", d => _worktimeOptions.Value, ExpireMode.Absolute, TimeSpan.FromDays(1)); var categoryId = GetCorrectCategory(worktimeSettings); var ivrList = _ivrCacheManager.GetIvrs(); var ivr = ivrList.First(x => x.IvrCategoryId == categoryId && x.IsRoot); return ivr; } private CorrectIvr GetCorrectIvr(string to) { var worktimeSettings = _worktimeCache.GetOrAdd("worktimesettings", d => _worktimeOptions.Value, ExpireMode.Absolute, TimeSpan.FromDays(1)); var correct = GetCorrectCategory(worktimeSettings.LineSetting.First(x => x.NumNo == to)); return correct; } private CorrectIvr GetCorrectCategory(LineSetting settings) { if (!settings.WorkDay.Contains((int)DateTime.Now.DayOfWeek)) return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Group, ReturnValue = settings.RestToGroup }; var time = TimeOnly.FromDateTime(DateTime.Now); if ((time >= TimeOnly.Parse(settings.MorningBegin) && time <= TimeOnly.Parse(settings.MorningEnd)) || (time >= TimeOnly.Parse(settings.AfterBegin) && time <= TimeOnly.Parse(settings.AfterEnd))) { if (!string.IsNullOrEmpty(settings.WorkCategory)) { return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Ivr, ReturnValue = settings.WorkCategory }; } else { return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Group, ReturnValue = settings.WorkToGroup }; } } else { if (!string.IsNullOrEmpty(settings.RestCategory)) { return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Ivr, ReturnValue = settings.RestCategory }; } else { return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Group,ReturnValue = settings.RestToGroup }; } } } public class CorrectIvr { public string ReturnValue { get; set; } public ECorrectIvr eCorrectIvr { get; set; } } public enum ECorrectIvr { Ivr = 0, Group = 1, } private string GetCorrectCategory(WorkTimeSettings settings) { if (!settings.WorkDay.Contains((int)DateTime.Now.DayOfWeek)) return settings.RestCategory; var time = TimeOnly.FromDateTime(DateTime.Now); if ((time >= TimeOnly.Parse(settings.MorningBegin) && time <= TimeOnly.Parse(settings.MorningEnd)) || (time >= TimeOnly.Parse(settings.AfterBegin) && time <= TimeOnly.Parse(settings.AfterEnd)) ) return settings.WorkCategory; return settings.RestCategory; } } }