using Hotline.Caches; using Hotline.CallCenter.Calls; using Hotline.CallCenter.Devices; using Hotline.CallCenter.Ivrs; using Hotline.Settings; using Hotline.Share.Enums.CallCenter; using Hotline.Share.Notifications; using MediatR; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NewRock.Sdk; using NewRock.Sdk.Transfer.Connect.Request; using NewRock.Sdk.Transfer.Queue.Request; using Oracle.ManagedDataAccess.Types; using XF.Domain.Cache; using XF.Domain.Constants; namespace Hotline.Application.Handlers.CallCenter.FlowControl { public class IncomingNotificationHandler : INotificationHandler { private readonly ICallRepository _callRepository; private readonly ICallDetailRepository _callDetailRepository; private readonly ISystemSettingCacheManager _systemSettingCacheManager; private readonly IIvrCacheManager _ivrCacheManager; private readonly INewRockClient _newRockClient; private readonly IOptionsSnapshot _options; private readonly ITypedCache> _worktimeCache; private readonly ILogger _logger; private readonly ISystemSettingGroupRepository _systemSettingGroupRepository; private readonly ISystemSettingRepository _systemSettingRepository; private readonly ITrunkIvrManagerRepository _trunkIvrManagerRepository; private readonly ICallCacheManager _callCacheManager; public IncomingNotificationHandler( ICallRepository callRepository, ICallDetailRepository callDetailRepository, ISystemSettingCacheManager systemSettingCacheManager, IIvrCacheManager ivrCacheManager, INewRockClient newRockClient, IOptionsSnapshot options, ITypedCache> worktimeCache, ILogger logger, ISystemSettingGroupRepository systemSettingGroupRepository, ISystemSettingRepository systemSettingRepository, ITrunkIvrManagerRepository trunkIvrManagerRepository, ICallCacheManager callCacheManager) { _callRepository = callRepository; _callDetailRepository = callDetailRepository; _systemSettingCacheManager = systemSettingCacheManager; _ivrCacheManager = ivrCacheManager; _newRockClient = newRockClient; _options = options; _worktimeCache = worktimeCache; _logger = logger; _systemSettingGroupRepository = systemSettingGroupRepository; _systemSettingRepository = systemSettingRepository; _trunkIvrManagerRepository = trunkIvrManagerRepository; _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),true,x=>x.CreationTime, 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); //TODO IVR处理 var setting = _systemSettingCacheManager.GetSetting(SettingConstants.IVRConfig); if (bool.Parse(setting.SettingValue)) { var correct = GetCorrectIvr(notification.Visitor.To); //var ivr = GetCorrectIvr(); switch (correct.eCorrectIvr) { 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); //写入进入IVR流程 model.InIvrTime = DateTime.Now; await _callRepository.UpdateAsync(model, cancellationToken); var detailTwo = new CallDetail() { CallId = model.Id, CallStatus = ECallStatus.InIvr, OMCallId = notification.Visitor.CallId, ConversationId = notification.Visitor.Id, EventName = notification.Attribute, FromNo = notification.Visitor.From, ToNo = notification.Visitor.To, }; await _callDetailRepository.AddAsync(detail, 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.InQueueTime = DateTime.Now; await _callRepository.UpdateAsync(model, cancellationToken); //处理队列记录 _callCacheManager.AddCallCache(model); break; default: //TODO 跳转默认分机组 break; } } else { //TODO 跳转默认分机组 } } } private CorrectIvr GetCorrectIvr(string to) { var worktimeSettings = _worktimeCache.GetOrAdd("worktimesettings", d => { var settings = _trunkIvrManagerRepository.QueryAsync(x=>x.IsEnable).GetAwaiter().GetResult(); return settings; }, ExpireMode.Absolute); var correct = GetCorrectCategory(worktimeSettings.First(x=>x.TrunkId == to)); return correct; } public class CorrectIvr { public string ReturnValue { get; set; } public ECorrectIvr eCorrectIvr { get; set; } } private CorrectIvr GetCorrectCategory(TrunkIvrManager settings) { if (!settings.WorkDay.Any(x=>x.weekValue == ((int)DateTime.Now.DayOfWeek).ToString())) return new CorrectIvr() { eCorrectIvr = settings.RestCategory != "" ? ECorrectIvr.Ivr : ECorrectIvr.Group, ReturnValue = settings.RestCategory != "" ? settings.RestCategory : 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)) ) { return new CorrectIvr() { eCorrectIvr = settings.WorkCategory != "" ? ECorrectIvr.Ivr : ECorrectIvr.Group, ReturnValue = settings.WorkCategory != "" ? settings.WorkCategory : settings.WorkToGroup }; } else { return new CorrectIvr() { eCorrectIvr = settings.RestCategory != "" ? ECorrectIvr.Ivr : ECorrectIvr.Group, ReturnValue = settings.RestCategory != "" ? settings.RestCategory : settings.RestToGroup }; } } } }