Dun.Jason 1 年之前
父节点
当前提交
c88abaafa0
共有 29 个文件被更改,包括 209 次插入25 次删除
  1. 1 1
      src/CallCenter.Api/Controllers/HomeController.cs
  2. 86 0
      src/CallCenter.Application/CacheManager/CallRecordFailManager.cs
  3. 1 1
      src/CallCenter.Application/Handlers/CallState/AlertExtToOuterNotificationHandler.cs
  4. 1 1
      src/CallCenter.Application/Handlers/CallState/AlertMenuToOuterNotificationHandler.cs
  5. 1 1
      src/CallCenter.Application/Handlers/CallState/AlertVisitorToExtNotificationHandler.cs
  6. 1 1
      src/CallCenter.Application/Handlers/CallState/DtmfNotificationHandler.cs
  7. 2 2
      src/CallCenter.Application/Handlers/CallState/RingExtToOuterNotificationHandler.cs
  8. 1 1
      src/CallCenter.Application/Handlers/CallState/RingVisitorToExtNotificationHandler.cs
  9. 1 1
      src/CallCenter.Application/Handlers/FlowControl/AnswerExtToOuterNotificationHandler.cs
  10. 1 1
      src/CallCenter.Application/Handlers/FlowControl/AnswerViisitorToExtNotificationHandler.cs
  11. 1 1
      src/CallCenter.Application/Handlers/FlowControl/AnsweredExtToOuterNotificationHandler.cs
  12. 1 1
      src/CallCenter.Application/Handlers/FlowControl/AnsweredExtToOuterToExtNotificationHandler.cs
  13. 1 1
      src/CallCenter.Application/Handlers/FlowControl/AnsweredVisitorToExtNotificationHandler.cs
  14. 1 1
      src/CallCenter.Application/Handlers/FlowControl/ByeExtAndOuterOneNotificationHandler.cs
  15. 1 1
      src/CallCenter.Application/Handlers/FlowControl/ByeExtAndOuterTwoNotificationHandler.cs
  16. 1 1
      src/CallCenter.Application/Handlers/FlowControl/ByeOuterAndOuterNotificationHandler.cs
  17. 1 1
      src/CallCenter.Application/Handlers/FlowControl/ByeVisitorAndExtNotificationHandler.cs
  18. 2 1
      src/CallCenter.Application/Handlers/FlowControl/ByeVisitorAndMenuNotificationHandler.cs
  19. 19 3
      src/CallCenter.Application/Handlers/FlowControl/CdrNotificationHandler.cs
  20. 1 1
      src/CallCenter.Application/Handlers/FlowControl/DivertVisitorToExtNotificationHandler.cs
  21. 1 1
      src/CallCenter.Application/Handlers/FlowControl/EndOfAnnOuterToMenuNotificationHandler.cs
  22. 1 1
      src/CallCenter.Application/Handlers/FlowControl/EndOfAnnVisitorToMenuNotificationHandler.cs
  23. 2 1
      src/CallCenter.Application/Handlers/FlowControl/IncomingNotificationHandler.cs
  24. 16 0
      src/CallCenter.Repository.SqlSugar/BaseRepository.cs
  25. 19 0
      src/CallCenter.Repository.SqlSugar/CallRecordFailRepository.cs
  26. 19 0
      src/CallCenter.Share/Enums/EFailType.cs
  27. 16 0
      src/CallCenter/Calls/CallRecordFail.cs
  28. 8 0
      src/CallCenter/Calls/ICallRecordFailRepository.cs
  29. 2 0
      src/XF.Domain.Repository/IRepositorySqlSugar.cs

+ 1 - 1
src/CallCenter.Api/Controllers/HomeController.cs

@@ -63,7 +63,7 @@ public class HomeController : BaseController
     {
         var db = _uow.Db;
         db.DbMaintenance.CreateDatabase();
-        db.CodeFirst.InitTables<Call>();
+        db.CodeFirst.InitTables<CallRecordFail>();
         return Task.CompletedTask;
     }
 }

+ 86 - 0
src/CallCenter.Application/CacheManager/CallRecordFailManager.cs

@@ -0,0 +1,86 @@
+using CallCenter.Application.Handlers;
+using CallCenter.Calls;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using System.Net.Http;
+using System.Text;
+using System.Text.Json;
+using System.Threading;
+
+namespace CallCenter.Application.CacheManager
+{
+    public class CallRecordFailManager : BackgroundService
+    {
+        private readonly IServiceScopeFactory _serviceScopeFactory;
+
+        public CallRecordFailManager(IServiceScopeFactory serviceScopeFactory)
+        {
+            _serviceScopeFactory = serviceScopeFactory;
+        }
+
+
+        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+        {
+            using var sc = _serviceScopeFactory.CreateScope();
+            var _logger = sc.ServiceProvider.GetService<ILogger<CallRecordFailManager>>();
+            var time = TimeSpan.FromMinutes(1);
+            while (!stoppingToken.IsCancellationRequested)
+            {
+                using var scope = _serviceScopeFactory.CreateScope();
+                var _callRecordFailRepository = scope.ServiceProvider.GetService<ICallRecordFailRepository>();
+                var list = await _callRecordFailRepository.QueryAsync();
+                if (list.Count > 0)
+                {
+                    var _sendCallRecordOptions = _serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService<IOptionsSnapshot<SendCallRecord>>();
+                    var _httpClientFactory = scope.ServiceProvider.GetService<IHttpClientFactory>();
+                    foreach (var item in list)
+                    {
+                        try
+                        {
+                            using var client = _httpClientFactory.CreateClient();
+                            client.DefaultRequestHeaders.ConnectionClose = true;
+                            var content = new StringContent(item.FailString, Encoding.UTF8, "application/json");
+                            HttpResponseMessage responseMessage;
+                            switch (item.FailType)
+                            {
+                                case Share.Enums.EFailType.CallRecord:
+                                    responseMessage = await client.PostAsync(_sendCallRecordOptions.Value.FwUrl, content);
+                                    break;
+                                case Share.Enums.EFailType.NotReceived:
+                                    responseMessage = await client.PostAsync(_sendCallRecordOptions.Value.NotReceivedUrl, content);
+                                    break;
+                                default:
+                                    responseMessage = await client.PostAsync(_sendCallRecordOptions.Value.FwUrl, content);
+                                    break;
+                            }
+                            var respContent = responseMessage.Content;
+                            var respContentString = await respContent.ReadAsStringAsync();
+                            var result = JsonSerializer.Deserialize<FwResult>(respContentString);
+                            switch (item.FailType)
+                            {
+                                case Share.Enums.EFailType.CallRecord:
+                                    _logger.LogInformation("推送通话报告结果:" + respContentString);
+                                    break;
+                                case Share.Enums.EFailType.NotReceived:
+                                    _logger.LogInformation("推送未接听报告结果:" + respContentString);
+                                    break;
+                                default:
+                                    break;
+                            }
+                            //推送成功就删除数据
+                            await _callRecordFailRepository.RemoveAsync(item);
+                        }
+                        catch (Exception ex)
+                        {
+                            _logger.LogInformation("推送通话报告失败:" + ex.Message + " 错误ID:" + item.Id);
+                        }
+                    }
+                }
+
+                await Task.Delay(time, stoppingToken);
+            }
+        }
+    }
+}

+ 1 - 1
src/CallCenter.Application/Handlers/CallState/AlertExtToOuterNotificationHandler.cs

@@ -29,7 +29,7 @@ namespace CallCenter.Application.Handlers
             string telNo = notification.Outer.From != "" ? notification.Outer.From : notification.TelNo;
             if (!string.IsNullOrEmpty(telNo))
             {
-                var model =await _callRepository.GetAsync(x => x.ConversationId==notification.Outer.Id && x.ToNo==notification.Outer.To && x.CreationTime>=DateTime.Now.AddHours(-2), cancellationToken);
+                var model =await _callRepository.GetAsync(x => x.ConversationId==notification.Outer.Id && x.ToNo==notification.Outer.To && x.CreationTime>=DateTime.Now.AddHours(-2),true,x=>x.CreationTime, cancellationToken);
                 var workModel = _userCacheManager.GetWorkByTel(telNo);
                 if (model!=null)
                 {

+ 1 - 1
src/CallCenter.Application/Handlers/CallState/AlertMenuToOuterNotificationHandler.cs

@@ -20,7 +20,7 @@ namespace CallCenter.Application.Handlers
         {
             var model = await _callRepository.GetAsync(
                 x => x.ConversationId == notification.Outer.Id && x.ToNo == notification.Outer.To &&
-                     x.Trunk == notification.Outer.Trunk && x.CreationTime >= DateTime.Now.AddHours(-2),
+                     x.Trunk == notification.Outer.Trunk && x.CreationTime >= DateTime.Now.AddHours(-2),true,x=>x.CreationTime,
                 cancellationToken);
             if (model!=null)
             {

+ 1 - 1
src/CallCenter.Application/Handlers/CallState/AlertVisitorToExtNotificationHandler.cs

@@ -20,7 +20,7 @@ namespace CallCenter.Application.Handlers
         {
             var model = await _callRepository.GetAsync(
                 x => x.ConversationId == notification.Visitor.Id &&
-                     x.FromNo == notification.Visitor.From && x.CreationTime>=DateTime.Now.AddHours(-2), cancellationToken);
+                     x.FromNo == notification.Visitor.From && x.CreationTime>=DateTime.Now.AddHours(-2),true,x=>x.CreationTime, cancellationToken);
             if (model!=null)
             {
                 model.CallStatus = ECallStatus.Alert;

+ 1 - 1
src/CallCenter.Application/Handlers/CallState/DtmfNotificationHandler.cs

@@ -36,7 +36,7 @@ namespace CallCenter.Application.Handlers
             string info = string.Empty;
             var model = await _callRepository.GetAsync(
                 x => x.ConversationId == notification.Visitor.Id && x.FromNo == notification.Visitor.From &&
-                     x.CreationTime >= DateTime.Now.AddHours(-2), cancellationToken);
+                     x.CreationTime >= DateTime.Now.AddHours(-2),true,x=>x.CreationTime, cancellationToken);
             if (model == null)
             {
                 model = await _callRepository.GetAsync(

+ 2 - 2
src/CallCenter.Application/Handlers/CallState/RingExtToOuterNotificationHandler.cs

@@ -20,12 +20,12 @@ namespace CallCenter.Application.Handlers
         public async Task Handle(RingExtToOuterNotification notification, CancellationToken cancellationToken)
         {
             var model = await _callRepository.GetAsync(x =>
-                x.FromNo == notification.TelNo && x.ToNo == notification.Outer.To && x.CreationTime >=DateTime.Now.AddHours(-2), cancellationToken);
+                x.FromNo == notification.TelNo && x.ToNo == notification.Outer.To && x.CreationTime >=DateTime.Now.AddHours(-2),true,x=>x.CreationTime, cancellationToken);
             if (model==null)
             {
                 model = await _callRepository.GetAsync(
                     x => x.ConversationId == notification.Outer.Id && x.ToNo == notification.Outer.To &&
-                         x.Trunk == notification.Outer.Trunk, cancellationToken);
+                         x.Trunk == notification.Outer.Trunk,true,x=>x.CreationTime, cancellationToken);
             }
                        
 

+ 1 - 1
src/CallCenter.Application/Handlers/CallState/RingVisitorToExtNotificationHandler.cs

@@ -33,7 +33,7 @@ namespace CallCenter.Application.Handlers
         {
             var model = await _callRepository.GetAsync(
                 x => x.ConversationId == notification.Visitor.Id &&
-                     x.FromNo == notification.Visitor.From && x.CreationTime>=DateTime.Now.AddHours(-2), cancellationToken);
+                     x.FromNo == notification.Visitor.From && x.CreationTime>=DateTime.Now.AddHours(-2),true,x=>x.CreationTime, cancellationToken);
             if (model!=null)
             {
                 model.CallStatus = ECallStatus.Ring;

+ 1 - 1
src/CallCenter.Application/Handlers/FlowControl/AnswerExtToOuterNotificationHandler.cs

@@ -26,7 +26,7 @@ namespace CallCenter.Application.Handlers
         {
             var model =await _callRepository.GetAsync(
                 x => x.ConversationId == notification.Outer.Id && x.ToNo == notification.Outer.To &&
-                     x.Trunk == notification.Outer.Trunk && x.CreationTime >= DateTime.Now.AddHours(-2),
+                     x.Trunk == notification.Outer.Trunk && x.CreationTime >= DateTime.Now.AddHours(-2),true,x=>x.CreationTime,
                 cancellationToken);
             if (model!=null)
             {

+ 1 - 1
src/CallCenter.Application/Handlers/FlowControl/AnswerViisitorToExtNotificationHandler.cs

@@ -33,7 +33,7 @@ namespace CallCenter.Application.Handlers
         {
             var model = await _callRepository.GetAsync(
                 x => x.ConversationId == notification.Visitor.Id &&
-                     x.FromNo == notification.Visitor.From && x.CreationTime >= DateTime.Now.AddHours(-2), cancellationToken);
+                     x.FromNo == notification.Visitor.From && x.CreationTime >= DateTime.Now.AddHours(-2),true,x=>x.CreationTime, cancellationToken);
             if (model != null)
             {
                 model.CallStatus = ECallStatus.Answer;

+ 1 - 1
src/CallCenter.Application/Handlers/FlowControl/AnsweredExtToOuterNotificationHandler.cs

@@ -26,7 +26,7 @@ namespace CallCenter.Application.Handlers
         {
             var model = await _callRepository.GetAsync(
                 x => x.ConversationId == notification.Outer.Id &&
-                     x.FromNo == notification.Outer.From && x.ToNo == notification.Outer.To && x.CreationTime >= DateTime.Now.AddHours(-2), cancellationToken);
+                     x.FromNo == notification.Outer.From && x.ToNo == notification.Outer.To && x.CreationTime >= DateTime.Now.AddHours(-2),true,x=>x.CreationTime, cancellationToken);
             if (model != null)
             {
                 model.CallStatus = ECallStatus.Answered;

+ 1 - 1
src/CallCenter.Application/Handlers/FlowControl/AnsweredExtToOuterToExtNotificationHandler.cs

@@ -24,7 +24,7 @@ namespace CallCenter.Application.Handlers
         {
             var model = await _callRepository.GetAsync(x =>
                 x.ConversationId == notification.Outer.Id && x.ToNo == notification.Outer.To &&
-                x.Trunk == notification.Outer.Trunk && x.CreationTime >= DateTime.Now.AddHours(-2),cancellationToken);
+                x.Trunk == notification.Outer.Trunk && x.CreationTime >= DateTime.Now.AddHours(-2),true,x=>x.CreationTime,cancellationToken);
             if (model!=null)
             {
                 model.CallStatus = ECallStatus.Answered;

+ 1 - 1
src/CallCenter.Application/Handlers/FlowControl/AnsweredVisitorToExtNotificationHandler.cs

@@ -32,7 +32,7 @@ namespace CallCenter.Application.Handlers
         {
             var model = await _callRepository.GetExtAsync(
                 x => x.ConversationId == notification.Visitor.Id &&
-                     x.FromNo == notification.Visitor.From && x.CreationTime >= DateTime.Now.AddHours(-2),x=>x.Includes(d=>d.CallDetails));
+                     x.FromNo == notification.Visitor.From && x.CreationTime >= DateTime.Now.AddHours(-2),true,x=>x.CreationTime,x=>x.Includes(d=>d.CallDetails));
             if (model != null)
             {
                 model.CallStatus = ECallStatus.Answered;

+ 1 - 1
src/CallCenter.Application/Handlers/FlowControl/ByeExtAndOuterOneNotificationHandler.cs

@@ -26,7 +26,7 @@ namespace CallCenter.Application.Handlers
         public async Task Handle(ByeExtAndOuterOneNotification notification, CancellationToken cancellationToken)
         {
             var model = await _callRepository.GetAsync(
-                x => x.ConversationId == notification.Outer.Id &&  x.ToNo == notification.Outer.To && x.CreationTime>=DateTime.Now.AddHours(-2), cancellationToken);
+                x => x.ConversationId == notification.Outer.Id &&  x.ToNo == notification.Outer.To && x.CreationTime>=DateTime.Now.AddHours(-2),true,x=>x.CreationTime, cancellationToken);
             if (model != null)
             {
                 model.CallStatus = ECallStatus.Bye;

+ 1 - 1
src/CallCenter.Application/Handlers/FlowControl/ByeExtAndOuterTwoNotificationHandler.cs

@@ -25,7 +25,7 @@ namespace CallCenter.Application.Handlers
         public async Task Handle(ByeExtAndOuterTwoNotification notification, CancellationToken cancellationToken)
         {
             var model = await _callRepository.GetAsync(
-                x => x.ConversationId == notification.Outer.Id  && x.ToNo == notification.Outer.To && x.CreationTime>=DateTime.Now.AddHours(-2), cancellationToken);
+                x => x.ConversationId == notification.Outer.Id  && x.ToNo == notification.Outer.To && x.CreationTime>=DateTime.Now.AddHours(-2),true,x=>x.CreationTime, cancellationToken);
             if (model != null)
             {
                 model.CallStatus = ECallStatus.Bye;

+ 1 - 1
src/CallCenter.Application/Handlers/FlowControl/ByeOuterAndOuterNotificationHandler.cs

@@ -20,7 +20,7 @@ namespace CallCenter.Application.Handlers
         {
             var model = await _callRepository.GetAsync(x =>
                 x.ConversationId == notification.Outer.Id && x.FromNo == notification.Outer.From &&
-                x.ToNo == notification.Outer.To && x.CreationTime >= DateTime.Now.AddHours(-2));
+                x.ToNo == notification.Outer.To && x.CreationTime >= DateTime.Now.AddHours(-2),true,x=>x.CreationTime,cancellationToken);
             if (model!=null)
             {
                 model.CallStatus = ECallStatus.Bye;

+ 1 - 1
src/CallCenter.Application/Handlers/FlowControl/ByeVisitorAndExtNotificationHandler.cs

@@ -28,7 +28,7 @@ namespace CallCenter.Application.Handlers
         {
             var model = await _callRepository.GetAsync(
                 x => x.ConversationId == notification.Visitor.Id && 
-                     x.FromNo == notification.Visitor.From && x.CreationTime>=DateTime.Now.AddHours(-2), cancellationToken);
+                     x.FromNo == notification.Visitor.From && x.CreationTime>=DateTime.Now.AddHours(-2),true,x=>x.CreationTime, cancellationToken);
             if (model != null)
             {
                 model.CallStatus = ECallStatus.Bye;

+ 2 - 1
src/CallCenter.Application/Handlers/FlowControl/ByeVisitorAndMenuNotificationHandler.cs

@@ -3,6 +3,7 @@ using CallCenter.Calls;
 using CallCenter.Notifications;
 using CallCenter.Realtimes;
 using CallCenter.Share.Notifications;
+using K4os.Hash.xxHash;
 using MediatR;
 using System;
 using System.Collections.Generic;
@@ -32,7 +33,7 @@ namespace CallCenter.Application.Handlers.FlowControl
 
         public async Task Handle(ByeVisitorAndMenuNotification notification, CancellationToken cancellationToken)
         {
-            var model = await _callRepository.GetAsync(x => x.ConversationId == notification.Visitor.Id && x.FromNo == notification.Visitor.From && x.CreationTime >= DateTime.Now.AddHours(-2), cancellationToken);
+            var model = await _callRepository.GetAsync(x => x.ConversationId == notification.Visitor.Id && x.FromNo == notification.Visitor.From && x.CreationTime >= DateTime.Now.AddHours(-2),true,x=>x.CreationTime, cancellationToken);
             if (model!=null)
             {
                 model.CallStatus = Share.Enums.ECallStatus.Bye;

+ 19 - 3
src/CallCenter.Application/Handlers/FlowControl/CdrNotificationHandler.cs

@@ -28,9 +28,10 @@ namespace CallCenter.Application.Handlers
         private readonly IRealtimeService _realtimeService;
         private readonly IUserCacheManager _userCacheManager;
         private readonly IWorkRepository _workRepository;
+        private readonly ICallRecordFailRepository _callRecordFailRepository;
 
 
-        public CdrNotificationHandler(ICallRecordRepository callRecordRepository, ICallDetailRepository callDetailRepository, ICallRepository callRepository, IOptionsSnapshot<SendCallRecord> sendCallRecordOptions, IHttpClientFactory httpClientFactory,ILogger<CdrNotificationHandler> logger,IRealtimeService realtimeService,IUserCacheManager userCacheManager,IWorkRepository workRepository)
+        public CdrNotificationHandler(ICallRecordRepository callRecordRepository, ICallDetailRepository callDetailRepository, ICallRepository callRepository, IOptionsSnapshot<SendCallRecord> sendCallRecordOptions, IHttpClientFactory httpClientFactory,ILogger<CdrNotificationHandler> logger,IRealtimeService realtimeService,IUserCacheManager userCacheManager,IWorkRepository workRepository,ICallRecordFailRepository callRecordFailRepository)
         {
             _callRecordRepository = callRecordRepository;
             _callDetailRepository = callDetailRepository;
@@ -41,6 +42,7 @@ namespace CallCenter.Application.Handlers
             _realtimeService = realtimeService;
             _userCacheManager = userCacheManager;
             _workRepository = workRepository;
+            _callRecordFailRepository = callRecordFailRepository;
         }
 
 
@@ -163,6 +165,7 @@ namespace CallCenter.Application.Handlers
                             var list = new List<OutCallDto>();
                             list.Add(callDto);
 
+                            string respContentString = "";
                             try
                             {
                                 using var client = _httpClientFactory.CreateClient();
@@ -172,12 +175,19 @@ namespace CallCenter.Application.Handlers
                                 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);
+                                respContentString = await respContent.ReadAsStringAsync(cancellationToken);
                                 var result = JsonSerializer.Deserialize<FwResult>(respContentString);
                                 _logger.LogInformation("推送通话报告结果:" + respContentString);
                             }
                             catch (Exception ex)
                             {
+                                //新增未推送成功记录
+                                var callRecordFail = new CallRecordFail();
+                                callRecordFail.FailType = EFailType.CallRecord;
+                                callRecordFail.FailString = respContentString;
+                                callRecordFail.FailReason = ex.Message;
+                                await _callRecordFailRepository.AddAsync(callRecordFail, cancellationToken);
+                               
                                 _logger.LogInformation("推送通话报告失败:" + ex.Message);
                                 //throw new UserFriendlyException(ex.Message);
                             }
@@ -231,12 +241,18 @@ namespace CallCenter.Application.Handlers
                                         var content = new StringContent(requestContent, Encoding.UTF8, "application/json");
                                         var responseMessage = await client.PostAsync(_sendCallRecordOptions.Value.NotReceivedUrl, content, cancellationToken);
                                         var respContent = responseMessage.Content;
-                                        var respContentString = await respContent.ReadAsStringAsync(cancellationToken);
+                                        respContentString = await respContent.ReadAsStringAsync(cancellationToken);
                                         var result = JsonSerializer.Deserialize<FwResult>(respContentString);
                                         _logger.LogInformation("推送未接听报告结果:" + respContentString);
                                     }
                                     catch (Exception ex)
                                     {
+                                        //新增未推送成功记录
+                                        var callRecordFail = new CallRecordFail();
+                                        callRecordFail.FailType = EFailType.NotReceived;
+                                        callRecordFail.FailString = respContentString;
+                                        callRecordFail.FailReason = ex.Message;
+                                        await _callRecordFailRepository.AddAsync(callRecordFail, cancellationToken);
                                         _logger.LogInformation("推送未接听报告失败:" + ex.Message);
                                         //throw new UserFriendlyException(ex.Message);
                                     }

+ 1 - 1
src/CallCenter.Application/Handlers/FlowControl/DivertVisitorToExtNotificationHandler.cs

@@ -20,7 +20,7 @@ namespace CallCenter.Application.Handlers
         {
             var model = await _callRepository.GetAsync(
                 x => x.ConversationId == notification.Visitor.Id && x.FromNo == notification.Visitor.From &&
-                     x.ToNo == notification.Visitor.To && x.CreationTime >= DateTime.Now.AddHours(-2),
+                     x.ToNo == notification.Visitor.To && x.CreationTime >= DateTime.Now.AddHours(-2),true,x=>x.CreationTime,
                 cancellationToken);
             if (model!=null)
             {

+ 1 - 1
src/CallCenter.Application/Handlers/FlowControl/EndOfAnnOuterToMenuNotificationHandler.cs

@@ -27,7 +27,7 @@ namespace CallCenter.Application.Handlers
         {
             var model =await _callRepository.GetAsync(
                 x => x.ConversationId == notification.Outer.Id && x.FromNo == notification.Outer.From &&
-                     x.ToNo == notification.Outer.To && x.CreationTime >= DateTime.Now.AddHours(-2), cancellationToken);
+                     x.ToNo == notification.Outer.To && x.CreationTime >= DateTime.Now.AddHours(-2),true,x=>x.CreationTime, cancellationToken);
             if (model!=null)
             {
                 model.CallStatus = ECallStatus.EndOfAnn;

+ 1 - 1
src/CallCenter.Application/Handlers/FlowControl/EndOfAnnVisitorToMenuNotificationHandler.cs

@@ -30,7 +30,7 @@ namespace CallCenter.Application.Handlers.FlowControl
         {
             var model = await _callRepository.GetAsync(
                 x => x.ConversationId == notification.Visitor.Id && x.FromNo == notification.Visitor.From &&
-                     x.ToNo == notification.Visitor.To && x.CreationTime >= DateTime.Now.AddHours(-2),
+                     x.ToNo == notification.Visitor.To && x.CreationTime >= DateTime.Now.AddHours(-2),true,x=>x.CreationTime,
                 cancellationToken);
 
             if (model!=null)

+ 2 - 1
src/CallCenter.Application/Handlers/FlowControl/IncomingNotificationHandler.cs

@@ -59,7 +59,8 @@ namespace CallCenter.Application.Handlers
         {
             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);
+                     x.FromNo == notification.Visitor.From && x.CreationTime >= DateTime.Now.AddHours(-2), true, x => x.CreationTime, cancellationToken);
+
             if (model != null)
             {
                 model.CallStatus = ECallStatus.Incoming;

+ 16 - 0
src/CallCenter.Repository.SqlSugar/BaseRepository.cs

@@ -182,6 +182,22 @@ namespace CallCenter.Repository.SqlSugar
             return await query.FirstAsync(predicate);
         }
 
+        public async Task<TEntity> GetExtAsync(Expression<Func<TEntity, bool>> predicate, bool isDesc, Expression<Func<TEntity, object>> orderby, Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> includes)
+        {
+            if (isDesc)
+            {
+                var query = Db.Queryable<TEntity>().OrderByDescending(orderby);
+                query = includes(query);
+                return await query.FirstAsync(predicate);
+            }
+            else
+            {
+                var query = Db.Queryable<TEntity>().OrderBy(orderby);
+                query = includes(query);
+                return await query.FirstAsync(predicate);
+            }
+        }
+
         public async Task<TEntity> GetExtAsync(string id, Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> includes)
         {
             var query = Db.Queryable<TEntity>();

+ 19 - 0
src/CallCenter.Repository.SqlSugar/CallRecordFailRepository.cs

@@ -0,0 +1,19 @@
+using CallCenter.BlackLists;
+using CallCenter.Calls;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Dependency;
+
+namespace CallCenter.Repository.SqlSugar
+{
+    public class CallRecordFailRepository : BaseRepository<CallRecordFail>, ICallRecordFailRepository, IScopeDependency
+    {
+        public CallRecordFailRepository(ISugarUnitOfWork<CallCenterDbContext> uow) : base(uow)
+        {
+        }
+    }
+}

+ 19 - 0
src/CallCenter.Share/Enums/EFailType.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CallCenter.Share.Enums
+{
+    public enum EFailType
+    {
+        [Description("通话记录")]
+        CallRecord = 1,
+
+        [Description("超时未接记录报告")]
+        NotReceived = 2,
+    }
+}

+ 16 - 0
src/CallCenter/Calls/CallRecordFail.cs

@@ -0,0 +1,16 @@
+using CallCenter.Share.Enums;
+using System.ComponentModel;
+using XF.Domain;
+
+namespace CallCenter.Calls
+{
+    [Description("通话记录失败记录")]
+    public class CallRecordFail: CreationEntity
+    {
+        public string FailString { get; set; }
+
+        public string FailReason { get; set; }
+
+        public EFailType FailType { get; set; }
+    }
+}

+ 8 - 0
src/CallCenter/Calls/ICallRecordFailRepository.cs

@@ -0,0 +1,8 @@
+using XF.Domain.Repository;
+
+namespace CallCenter.Calls
+{
+    public interface ICallRecordFailRepository: IRepository<CallRecordFail>
+    {
+    }
+}

+ 2 - 0
src/XF.Domain.Repository/IRepositorySqlSugar.cs

@@ -26,6 +26,8 @@ namespace XF.Domain.Repository
             Expression<Func<TEntity, bool>> predicate,
             Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> includes);
 
+        Task<TEntity> GetExtAsync(Expression<Func<TEntity, bool>> predicate, bool isDesc, Expression<Func<TEntity, object>> orderby, Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> includes);
+
         Task<TEntity> GetExtAsync(
             TKey id,
             Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> includes);