using CallCenter.Calls; using CallCenter.NewRock.Handlers; using CallCenter.Notifications; using CallCenter.Share.Dtos; using CallCenter.Share.Enums; using MediatR; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NewRock.Sdk.Extensions; using System.Collections.Generic; using System.Text; using System.Text.Json; using XF.Domain.Exceptions; namespace CallCenter.Application.Handlers { public class CdrNotificationHandler:INotificationHandler { private readonly ICallRecordRepository _callRecordRepository; private readonly ICallDetailRepository _callDetailRepository; private readonly ICallRepository _callRepository; private readonly IOptionsSnapshot _sendCallRecordOptions; private readonly IHttpClientFactory _httpClientFactory; private readonly ILogger _logger; public CdrNotificationHandler(ICallRecordRepository callRecordRepository, ICallDetailRepository callDetailRepository, ICallRepository callRepository, IOptionsSnapshot sendCallRecordOptions, IHttpClientFactory httpClientFactory,ILogger logger) { _callRecordRepository = callRecordRepository; _callDetailRepository = callDetailRepository; _callRepository = callRepository; _sendCallRecordOptions = sendCallRecordOptions; _httpClientFactory = httpClientFactory; _logger = logger; } public async Task Handle(CdrNotification notification, CancellationToken cancellationToken) { var callDetail = await _callDetailRepository.GetAsync(x => x.OMCallId == notification.CallId,true,x=>x.CreationTime, cancellationToken); if (callDetail!=null) { var model = new CallRecord() { CallId = callDetail.CallId, CdrId = notification.Id, CDRCallId = notification.CallId, TimeStart = notification.TimeStart, Group = notification.Group, Type = (ECDRType)Enum.Parse(typeof(ECDRType), notification.Type), Route = (ECDRRoute)Enum.Parse(typeof(ECDRRoute), notification.Route), CPN = notification.CPN, CDPN = notification.CDPN, TimeEnd = notification.TimeEnd, Duration = notification.Duration, TrunkNumber = notification.TrunkNumber, Recording = notification.Recording, RecCodec = notification.RecCodec, IsDown = false }; if (!string.IsNullOrEmpty(notification.VisitorId)) model.VisitorId = notification.VisitorId; if (!string.IsNullOrEmpty(notification.OuterId)) model.OuterId = notification.OuterId; await _callRecordRepository.AddAsync(model,cancellationToken); var callModel = await _callRepository.GetAsync(x => x.Id == callDetail.CallId, cancellationToken); bool ishave = false; if (callModel.CallType == ECallType.ExtToOuter) { ishave = true; } else { ishave = await _callDetailRepository.AnyAsync(x => (x.EventName == "RING" || x.EventName == "INCOMING") && x.OMCallId == notification.CallId && x.FromNo == notification.CPN && x.ToNo == notification.CDPN); } if (ishave) { if (callModel != null) { callModel.Duration = double.Parse(model.Duration); await _callRepository.UpdateAsync(callModel, cancellationToken); var call = await _callRepository.GetExtAsync(callModel.Id, x => x.Includes(d => d.CallDetails)); //TODO 推送通话报告 OutCallDto callDto = new OutCallDto(); callDto.CallId = callDetail.CallId; callDto.InfoType = EInfoType.Call; callDto.Direction = callModel.CallDirection; callDto.Cpn = callModel.FromNo ?? ""; callDto.Cdpn = callModel.ToNo ?? ""; if (callDto.Direction == ECallDirection.In) { callDto.Answered = call.CallDetails?.FirstOrDefault(x => x.EventName == "ANSWER")?.AnswerNo ?? call.CallDetails?.FirstOrDefault(x => x.EventName == "ANSWERED")?.AnswerNo ?? ""; callDto.OnTime = call.CallDetails?.FirstOrDefault(x => x.EventName == "ANSWER")?.CreationTime ?? call.CallDetails?.FirstOrDefault(x => x.EventName == "ANSWERED")?.CreationTime ?? null; callDto.OnState = call.CallDetails?.Any(x => x.EventName == "ANSWER" || x.EventName == "ANSWERED") == true ? EOnState.On : EOnState.NoOn; } else { //callDto.Answered = call.CallDetails?.FirstOrDefault(x => x.EventName == "ANSWERED")?.AnswerNo ?? ""; //callDto.OnTime = call.CallDetails?.FirstOrDefault(x => x.EventName == "ANSWERED")?.CreationTime; //callDto.OnState = call.CallDetails?.Any(x => x.EventName == "ANSWERED") == true ? EOnState.On : EOnState.NoOn; callDto.Answered = call.CallDetails?.FirstOrDefault(x => x.EventName == "ANSWER")?.AnswerNo ?? call.CallDetails?.FirstOrDefault(x => x.EventName == "ANSWERED")?.AnswerNo ?? ""; callDto.OnTime = call.CallDetails?.FirstOrDefault(x => x.EventName == "ANSWER")?.CreationTime ?? call.CallDetails?.FirstOrDefault(x => x.EventName == "ANSWERED")?.CreationTime ?? null; callDto.OnState = call.CallDetails?.Any(x => x.EventName == "ANSWER" || x.EventName == "ANSWERED") == true ? EOnState.On : EOnState.NoOn; } callDto.BeginTime = call.CreationTime; callDto.ByeTime = call.CallDetails?.FirstOrDefault(x => x.EventName == "BYE")?.CreationTime ?? DateTime.Now; callDto.TalkTime = call.Duration; callDto.SoundFileName = model.Recording; if (string.IsNullOrEmpty(callDto.SoundFileName)) { callDto.SoundFileName = call.CallDetails?.FirstOrDefault(x => x.EventName == "BYE" && !string.IsNullOrEmpty(x.Recording))?.Recording; } if (string.IsNullOrEmpty(callDto.SoundFileName)) { callDto.SoundFileName = (await _callRecordRepository.GetAsync(x => x.CallId == callModel.Id && !string.IsNullOrEmpty(x.Recording)))?.Recording; } callDto.EvaluateResult = ""; callDto.EndBy = call.EndBy; callDto.InIvrTime = call.InIvrTime; callDto.OutIvrTime = call.OutIvrTime; callDto.InGroupTime = call.InGroupTime; callDto.OutGroupTime = call.OutGroupTime; callDto.InSeaTime = call.InSeaTime; callDto.ConnSeaTime = call.ConnSeaTime; var list = new List(); list.Add(callDto); try { var client = _httpClientFactory.CreateClient(); client.DefaultRequestHeaders.ConnectionClose = true; var requestContent = JsonSerializer.Serialize(list); _logger.LogInformation(requestContent); var content = new StringContent(requestContent, Encoding.UTF8, "application/json"); var responseMessage = await client.PostAsync(_sendCallRecordOptions.Value.FwUrl, content, cancellationToken); var respContent = responseMessage.Content; var respContentString = await respContent.ReadAsStringAsync(cancellationToken); var result = JsonSerializer.Deserialize(respContentString); _logger.LogInformation("推送报告结果:" + respContentString); } catch (Exception ex) { throw new UserFriendlyException(ex.Message); } //HttpContent content = new } } } } } public class FwResult { public int code { get; set; } public string msg { get; set; } } }