Jason 1 ano atrás
pai
commit
0af44cc31f

+ 41 - 21
src/CallCenter.Api/appsettings.Development.json

@@ -69,7 +69,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         //"NumNo": "12345",
@@ -79,11 +80,12 @@
         "AfterBegin": "12:00",
         "AfterEnd": "23:59",
         "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
-        "WorkCategory": "08db2b5d-50b8-4830-83c5-ebe2c3b4364e",
+        "WorkCategory": "",//"08db2b5d-50b8-4830-83c5-ebe2c3b4364e",
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": "2"
       },
       {
         "NumNo": "3490",
@@ -96,7 +98,8 @@
         "RestCategory": "",
         "WorkToGroup": "2",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12319",
@@ -109,7 +112,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "3497",
@@ -122,7 +126,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12310",
@@ -135,7 +140,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12312",
@@ -148,7 +154,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12313",
@@ -161,7 +168,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12318",
@@ -174,7 +182,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12336",
@@ -187,7 +196,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12338",
@@ -200,7 +210,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12349",
@@ -213,7 +224,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12350",
@@ -226,7 +238,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12351",
@@ -239,7 +252,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12355",
@@ -252,7 +266,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12356",
@@ -265,7 +280,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12363",
@@ -278,7 +294,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "12385",
@@ -291,7 +308,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "96198",
@@ -304,7 +322,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       },
       {
         "NumNo": "96960",
@@ -317,7 +336,8 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1",
-        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2"
+        "EvaluateCategory": "08db1e04-70c8-4419-8d4a-9b7172678ab2",
+        "BusyGroup": ""
       }
     ]
   },

+ 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.Trunk==notification.Outer.Trunk && 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), cancellationToken);
                 var workModel = _userCacheManager.GetWorkByTel(telNo);
                 if (model!=null)
                 {

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

@@ -54,7 +54,7 @@ namespace CallCenter.Application.Handlers
                 string telNo = (string.IsNullOrEmpty(notification.Outer.From) || string.IsNullOrWhiteSpace(notification.Outer.From)) ? notification.TelNo : notification.Outer.From;
                 var callModel = new Call()
                 {
-                    CallStatus = ECallStatus.Alert,
+                    CallStatus = ECallStatus.Ring,
                     CallDirection = ECallDirection.Out,
                     CallType = ECallType.ExtToOuter,
                     ConversationId = notification.Outer.Id,
@@ -69,7 +69,7 @@ namespace CallCenter.Application.Handlers
                 var detail = new CallDetail()
                 {
                     CallId = callId,
-                    CallStatus = ECallStatus.Alert,
+                    CallStatus = ECallStatus.Ring,
                     ConversationId = notification.Outer.Id,
                     OMCallId = notification.Outer.CallId,
                     EventName = notification.Attribute,

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

@@ -26,8 +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.Trunk==notification.Outer.Trunk && 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), 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.Trunk==notification.Outer.Trunk && x.CreationTime>=DateTime.Now.AddHours(-2), cancellationToken);
+                x => x.ConversationId == notification.Outer.Id  && x.ToNo == notification.Outer.To && x.CreationTime>=DateTime.Now.AddHours(-2), cancellationToken);
             if (model != null)
             {
                 model.CallStatus = ECallStatus.Bye;

+ 19 - 0
src/CallCenter.Application/Handlers/FlowControl/IncomingNotificationHandler.cs

@@ -119,7 +119,26 @@ namespace CallCenter.Application.Handlers
                             break;
                         //直接转分机组
                         case ECorrectIvr.Group:
+
+                            //判断12333是否在排队
+#if DEBUG
+                        if(notification.TrunkId == "3496")
+#else
+                        if (notification.TrunkId == "12333")
+#endif
+                        {
+                            int count = _callCacheManager.GetCallQueueListByTrunk(notification.TrunkId);
+                            if (count>=2)
+                            {
+                                if (!string.IsNullOrEmpty(correct.BusyGroup))
+                                {
+                                    correct.ReturnValue = correct.BusyGroup;
+                                }
+                            }
+                        }
+
                             _logger.LogInformation("transfer to group.no:{groupNo}", correct.ReturnValue);
+
                             await _newRockClient.VisitorToGroupQueue(new VisitorToGroupQueueRequest()
                             {
                                 Attribute = "Queue",

+ 36 - 2
src/CallCenter.NewRock/DeviceManager.cs

@@ -20,6 +20,7 @@ using Group = NewRock.Sdk.Control.Request.Group;
 using CallCenter.Share.Enums;
 using CallCenter.Caches;
 using Microsoft.AspNetCore.Http;
+using CallCenter.Tools;
 
 namespace CallCenter.NewRock
 {
@@ -33,8 +34,9 @@ namespace CallCenter.NewRock
         private readonly IUserCacheManager _userCacheManager;
         private readonly ITelRestRepository _telRestRepository;
         private readonly ITelCacheManager _telCacheManager;
+        private readonly ICallDetailRepository _callDetailRepository;
 
-        public DeviceManager(INewRockClient newRockClient, IOptionsSnapshot<DeviceConfigs> options, IMapper mapper, ICallRepository callRepository, ITelGroupRepository telGroupRepository,IUserCacheManager userCacheManager, ITelRestRepository telRestRepository, ITelCacheManager telCacheManager)
+        public DeviceManager(INewRockClient newRockClient, IOptionsSnapshot<DeviceConfigs> options, IMapper mapper, ICallRepository callRepository, ITelGroupRepository telGroupRepository,IUserCacheManager userCacheManager, ITelRestRepository telRestRepository, ITelCacheManager telCacheManager, ICallDetailRepository callDetailRepository)
         {
             _newRockClient = newRockClient;
             _options = options;
@@ -44,6 +46,7 @@ namespace CallCenter.NewRock
             _userCacheManager = userCacheManager;
             _telRestRepository = telRestRepository;
             _telCacheManager = telCacheManager;
+            _callDetailRepository = callDetailRepository;
         }
 
         #region 查询
@@ -673,7 +676,7 @@ namespace CallCenter.NewRock
         /// <returns></returns>
         public async Task ExtToOuterAsync(string from, string to, CancellationToken cancellationToken, string trunkid = "")
         {
-            await _newRockClient.ExtToOuter(
+             var rsp = await _newRockClient.ExtToOuter(
                     new ExtToOuterRequest()
                     {
                         Attribute = "Connect",
@@ -684,6 +687,37 @@ namespace CallCenter.NewRock
                 _options.Value.ReceiveKey,
                 _options.Value.Expired,
                 cancellationToken);
+            //写入记录
+            string telNo = (string.IsNullOrEmpty(rsp.Outer.From) || string.IsNullOrWhiteSpace(rsp.Outer.From)) ? rsp.Ext.Id : rsp.Outer.From;
+            var workModel = _userCacheManager.GetWorkByTel(telNo);
+            var isp = PhoneIspTool.GetPhoneIsp(rsp.Outer.To);
+            var callModel = new Call()
+            {
+                CallStatus = ECallStatus.ExtOuterReady,
+                CallDirection = ECallDirection.Out,
+                CallType = ECallType.ExtToOuter,
+                ConversationId = rsp.Outer.Id,
+                FromNo = telNo,
+                ToNo = rsp.Outer.To,
+                Trunk = rsp.Outer.Trunk,
+                UserId = workModel.UserId,
+                UserName = workModel.UserName,
+                PhoneIsp = isp
+            };
+            callModel.Modified();
+            var callId = await _callRepository.AddAsync(callModel,cancellationToken);
+            //写入明细
+            var detail = new CallDetail()
+            {
+                CallId = callId,
+                CallStatus = ECallStatus.ExtOuterReady,
+                ConversationId = rsp.Outer.Id,
+                OMCallId = rsp.Outer.CallId,
+                EventName = "ExtOuterReady",//去电
+                FromNo = telNo,
+                ToNo = rsp.Outer.To,
+            };
+            await _callDetailRepository.AddAsync(detail, cancellationToken);
         }
 
         /// <summary>

+ 4 - 0
src/CallCenter/Caches/CallCacheManager.cs

@@ -42,6 +42,10 @@ namespace CallCenter.Caches
             return _cacheCall.GetListByPrefix().Where(x => x.GroupNo == groupNo).Count();
         }
 
+        public int GetCallQueueListByTrunk(string trunk)
+        {
+            return _cacheCall.GetListByPrefix().Where(x => x.TrunkNo == trunk).Count();
+        }
 
 
         public void RemoveCallCache(string id)

+ 2 - 0
src/CallCenter/Caches/ICallCacheManager.cs

@@ -10,6 +10,8 @@ namespace CallCenter.Caches
         int GetCallQueueList(string groupNo);
         void AddCallCache(Call call,string groupNo);
 
+        int GetCallQueueListByTrunk(string trunk);
+
         void RemoveCallCache(string id);
     }
 }

+ 8 - 6
src/CallCenter/Ivrs/IvrDomainService.cs

@@ -315,33 +315,33 @@ public class IvrDomainService : IIvrDomainService, IScopeDependency
     {
         if (isEvaluate)
         {
-            return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Ivr, ReturnValue = settings.EvaluateCategory };
+            return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Ivr, ReturnValue = settings.EvaluateCategory,BusyGroup = settings.BusyGroup };
         }
 
         if (!settings.WorkDay.Contains((int)DateTime.Now.DayOfWeek))
-            return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Group, ReturnValue = settings.RestToGroup };
+            return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Group, ReturnValue = settings.RestToGroup, BusyGroup = settings.BusyGroup };
         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 };
+                return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Ivr, ReturnValue = settings.WorkCategory, BusyGroup = settings.BusyGroup };
             }
             else
             {
-                return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Group, ReturnValue = settings.WorkToGroup };
+                return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Group, ReturnValue = settings.WorkToGroup, BusyGroup = settings.BusyGroup };
             }
         }
         else
         {
             if (!string.IsNullOrEmpty(settings.RestCategory))
             {
-                return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Ivr, ReturnValue = settings.RestCategory };
+                return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Ivr, ReturnValue = settings.RestCategory, BusyGroup = settings.BusyGroup };
             }
             else
             {
-                return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Group, ReturnValue = settings.RestToGroup };
+                return new CorrectIvr() { eCorrectIvr = ECorrectIvr.Group, ReturnValue = settings.RestToGroup, BusyGroup = settings.BusyGroup };
             }
         }
     }
@@ -351,6 +351,8 @@ public class IvrDomainService : IIvrDomainService, IScopeDependency
         public string ReturnValue { get; set; }
 
         public ECorrectIvr eCorrectIvr { get; set; }
+
+        public string BusyGroup { get; set; }
     }
 
 

+ 2 - 0
src/CallCenter/Settings/WorkTimeSettings.cs

@@ -59,5 +59,7 @@ namespace CallCenter.Settings
         public string WorkToGroup { get; set; }
         public string RestToGroup { get; set; }
         public string EvaluateCategory { get; set; }
+
+        public string BusyGroup { get; set; }
     }
 }

+ 0 - 4
src/NewRock.Sdk/NewRock.Sdk.csproj

@@ -6,10 +6,6 @@
     <Nullable>enable</Nullable>
   </PropertyGroup>
 
-  <ItemGroup>
-    <Folder Include="Transfer\Connect\Response\" />
-  </ItemGroup>
-
   <ItemGroup>
     <PackageReference Include="Mapster" Version="7.3.0" />
     <PackageReference Include="MediatR.Contracts" Version="1.0.1" />

+ 8 - 7
src/NewRock.Sdk/NewRockClient.cs

@@ -41,14 +41,15 @@ namespace NewRock.Sdk
                 using var respContent = responseMessage.Content;
                 var respContentString = await respContent.ReadAsStringAsync(cancellationToken);
                 _logger.LogInformation($"response: {respContentString}");
-                if (respContentString.Contains("<Event"))
-                    return default;
-
-                var authResult = respContentString.Authentication();
-                if (authResult != null)
+                if (!respContentString.Contains("<Event attribute=\"TRANSIENT\">"))
                 {
-                    throw new AuthenticationException(
-                        string.Format("请求认证失败, code: {code}, err: {err}", authResult.Code, authResult.Reason));
+                    var authResult = respContentString.Authentication();
+                    if (authResult != null)
+                    {
+                        throw new AuthenticationException(
+                            string.Format("请求认证失败, code: {code}, err: {err}", authResult.Code, authResult.Reason));
+                    }
+                    //return default;
                 }
 
                 return respContentString.DeserializeWithErrorMsg<TResponse>();

+ 45 - 0
src/NewRock.Sdk/Transfer/Connect/Response/ExtToOuterResponse.cs

@@ -0,0 +1,45 @@
+
+
+using System.Xml.Serialization;
+
+namespace NewRock.Sdk.Transfer.Connect.Response
+{
+    [XmlRoot("Event")]
+    public class ExtToOuterResponse: NewRockResponse
+    {
+        [XmlAttribute("attribute")]
+        public string Attribute { get; set; }
+
+        [XmlElement("outer")]
+        public ExtToOuterOuterResponse Outer { get; set; }
+
+        [XmlElement("ext")]
+        public ExtToOuterExtResponse Ext { get; set; }
+    }
+
+
+    public class ExtToOuterOuterResponse
+    {
+        [XmlAttribute("id")]
+        public string Id { get; set; }
+
+        [XmlAttribute("from")]
+        public string From { get; set; }
+
+        [XmlAttribute("to")]
+        public string To { get; set; }
+
+        [XmlAttribute("trunk")]
+        public string Trunk { get; set; }
+
+        [XmlAttribute("callid")]
+        public string CallId { get; set; }
+    }
+
+    public class ExtToOuterExtResponse
+    {
+        [XmlAttribute("id")]
+        public string Id { get; set; }
+    }
+
+}

+ 3 - 2
src/NewRock.Sdk/Transfer/INewRockClient.Transfer.cs

@@ -1,5 +1,6 @@
 using NewRock.Sdk.Transfer.Conference.Request;
 using NewRock.Sdk.Transfer.Connect.Request;
+using NewRock.Sdk.Transfer.Connect.Response;
 using NewRock.Sdk.Transfer.Queue.Request;
 
 namespace NewRock.Sdk
@@ -28,8 +29,8 @@ namespace NewRock.Sdk
         /// <param name="expired"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        Task<NewRockResponse?> ExtToOuter(ExtToOuterRequest request, string key, int expired,CancellationToken cancellationToken)
-            => ExecuteAsync<ExtToOuterRequest, NewRockResponse>(request, key, expired, cancellationToken);
+        Task<ExtToOuterResponse?> ExtToOuter(ExtToOuterRequest request, string key, int expired,CancellationToken cancellationToken)
+            => ExecuteAsync<ExtToOuterRequest, ExtToOuterResponse>(request, key, expired, cancellationToken);
 
         /// <summary>
         /// 来电转分机