admin 2 years ago
parent
commit
428cac9485

+ 40 - 37
src/CallCenter.Api/Controllers/TelController.cs

@@ -166,48 +166,48 @@ namespace CallCenter.Api.Controllers
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
-        [HttpPost("group")]
-        public async Task AddTelGroup([FromBody] AddTelGroupDto dto)
-        {
-            var works = await _workRepository.QueryAsync(d => dto.TelNos.Contains(d.TelNo) && !d.EndTime.HasValue);
-
-            await _deviceManager.AssginConfigGroupAsync(
-                dto.No,
-                dto.Distribution.ToString().ToLower(),
-                ext: works.Select(d => d.TelNo).ToList(),
-                voiceFile: dto.Voice ?? null,
-                cancellationToken: HttpContext.RequestAborted);
-
-            var group = _mapper.Map<TelGroup>(dto);
-            var tels = await _telRepository.QueryAsync(d => dto.TelNos.Contains(d.No));
-            group.Tels = tels;
-            await _telGroupRepository.AddNavTelsAsync(group, HttpContext.RequestAborted);
-            _cacheTelGroup.Remove(dto.No);
-        }
+        //[HttpPost("group")]
+        //public async Task AddTelGroup([FromBody] AddTelGroupDto dto)
+        //{
+        //    var works = await _workRepository.QueryAsync(d => dto.TelNos.Contains(d.TelNo) && !d.EndTime.HasValue);
+
+        //    await _deviceManager.AssginConfigGroupAsync(
+        //        dto.No,
+        //        dto.Distribution.ToString().ToLower(),
+        //        ext: works.Select(d => d.TelNo).ToList(),
+        //        voiceFile: dto.Voice ?? null,
+        //        cancellationToken: HttpContext.RequestAborted);
+
+        //    var group = _mapper.Map<TelGroup>(dto);
+        //    var tels = await _telRepository.QueryAsync(d => dto.TelNos.Contains(d.No));
+        //    group.Tels = tels;
+        //    await _telGroupRepository.AddNavTelsAsync(group, HttpContext.RequestAborted);
+        //    _cacheTelGroup.Remove(dto.No);
+        //}
 
         /// <summary>
         /// 更新分机组
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
-        [HttpPut("group")]
-        public async Task UpdateTelGroup([FromBody] UpdateTelGroupDto dto)
-        {
-            var works = await _workRepository.QueryAsync(d => dto.TelNos.Contains(d.TelNo) && !d.EndTime.HasValue);
-
-            await _deviceManager.AssginConfigGroupAsync(
-                dto.No,
-                dto.Distribution.ToString().ToLower(),
-                ext: works.Select(d => d.TelNo).ToList(),
-                voiceFile: dto.Voice ?? null,
-                cancellationToken: HttpContext.RequestAborted);
-
-            var group = _mapper.Map<TelGroup>(dto);
-            var tels = await _telRepository.QueryAsync(d => dto.TelNos.Contains(d.No));
-            group.Tels = tels;
-            await _telGroupRepository.UpdateNavTelsAsync(group, HttpContext.RequestAborted);
-            _cacheTelGroup.Remove(dto.No);
-        }
+        //[HttpPut("group")]
+        //public async Task UpdateTelGroup([FromBody] UpdateTelGroupDto dto)
+        //{
+        //    var works = await _workRepository.QueryAsync(d => dto.TelNos.Contains(d.TelNo) && !d.EndTime.HasValue);
+
+        //    await _deviceManager.AssginConfigGroupAsync(
+        //        dto.No,
+        //        dto.Distribution.ToString().ToLower(),
+        //        ext: works.Select(d => d.TelNo).ToList(),
+        //        voiceFile: dto.Voice ?? null,
+        //        cancellationToken: HttpContext.RequestAborted);
+
+        //    var group = _mapper.Map<TelGroup>(dto);
+        //    var tels = await _telRepository.QueryAsync(d => dto.TelNos.Contains(d.No));
+        //    group.Tels = tels;
+        //    await _telGroupRepository.UpdateNavTelsAsync(group, HttpContext.RequestAborted);
+        //    _cacheTelGroup.Remove(dto.No);
+        //}
 
         /// <summary>
         /// 分机休息
@@ -231,7 +231,7 @@ namespace CallCenter.Api.Controllers
             var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
             if (work is null)
                 throw new UserFriendlyException("当前坐席暂未进行工作");
-            var telRest = await _telDomainService.UnRestAsync(work.TelId, HttpContext.RequestAborted);
+            var telRest = await _telDomainService.UnRestAsync(work.UserId,work.TelId, HttpContext.RequestAborted);
             return _mapper.Map<TelRestDto>(telRest);
         }
 
@@ -441,5 +441,8 @@ namespace CallCenter.Api.Controllers
                 throw new UserFriendlyException("当前分机没有通话");
         }
 
+
+        //public async Task 
+
     }
 }

+ 35 - 6
src/CallCenter.Api/Controllers/TestSdkController.cs

@@ -44,7 +44,7 @@ namespace CallCenter.Api.Controllers
         /// </summary>
         /// <returns></returns>
         [HttpGet("QueryDeviceInfo")]
-        public async Task QueryDeviceInfo()
+        public async Task<QueryDeviceInfoResponse?> QueryDeviceInfo()
         {
             var result = await _client.QueryDeviceInfo(
                 new QueryDeviceInfoRequest { Attribute = "Query", DeviceInfo = string.Empty },
@@ -52,6 +52,7 @@ namespace CallCenter.Api.Controllers
                 _options.Value.Expired,
                 HttpContext.RequestAborted);
             _logger.LogInformation(System.Text.Json.JsonSerializer.Serialize(result));
+            return result;
         }
 
 
@@ -60,7 +61,7 @@ namespace CallCenter.Api.Controllers
         /// </summary>
         /// <returns></returns>
         [HttpPost("QueryExt")]
-        public async Task QueryExt(string extid)
+        public async Task<QueryExtResponse?> QueryExt(string extid)
         {
             var result = await _client.QueryExt(
                 new QueryExtRequest() { Attribute = "Query", Ext = new Ext() { Id = extid } },
@@ -69,6 +70,7 @@ namespace CallCenter.Api.Controllers
                 HttpContext.RequestAborted
             );
             _logger.LogInformation(System.Text.Json.JsonSerializer.Serialize(result));
+            return result;
         }
 
         /// <summary>
@@ -77,7 +79,7 @@ namespace CallCenter.Api.Controllers
         /// <param name="groupid"></param>
         /// <returns></returns>
         [HttpPost("QueryExtGroup")]
-        public async Task QueryExtGroup(string? groupid)
+        public async Task<QueryExtGroupResponse?> QueryExtGroup(string? groupid)
         {
             var result = await _client.QueryExtGroup(new QueryExtGroupRequest()
             {
@@ -87,6 +89,7 @@ namespace CallCenter.Api.Controllers
                 _options.Value.Expired,
                 HttpContext.RequestAborted);
             _logger.LogInformation(System.Text.Json.JsonSerializer.Serialize(result));
+            return result;
         }
 
         /// <summary>
@@ -244,8 +247,8 @@ namespace CallCenter.Api.Controllers
                 Attribute = "Assign",
                 Ext = new ConfigExt()
                 {
-                    Lineid = "IPPhone 21",
-                    Id = "212",
+                    Lineid = "IPPhone 14",
+                    Id = "8013",
                     //Staffid = "038",
                     Groups = new List<string>()
                     {
@@ -751,7 +754,6 @@ namespace CallCenter.Api.Controllers
 
         #endregion
 
-
         #region 语音管理命令
 
         /// <summary>
@@ -790,5 +792,32 @@ namespace CallCenter.Api.Controllers
 
         #endregion
 
+        #region 处理示忙的分机
+
+        [HttpGet("configdisturb")]
+        public async Task ConfigDisturb(string extid,string lineid)
+        {
+            var result = await _client.ConfigExt(new AssginConfigExtRequest()
+            {
+                Attribute = "Assign",
+                Ext = new ConfigExt()
+                {
+                    Lineid = lineid,
+                    Id = extid,
+                   
+                 
+                    No_Disturb = "off",
+                
+                }
+            },
+            _options.Value.ReceiveKey,
+            _options.Value.Expired,
+            HttpContext.RequestAborted);
+            _logger.LogInformation(System.Text.Json.JsonSerializer.Serialize(result));
+        }
+
+
+        #endregion
+
     }
 }

+ 7 - 7
src/CallCenter.Api/Realtimes/RealtimeService.cs

@@ -14,10 +14,10 @@ namespace CallCenter.Api.Realtimes
         private readonly IUserCacheManager _userCacheManager;
 
 
-        public RealtimeService(IHubContext<CallCenterHub> hubContext,IUserCacheManager userCacheManager)
+        public RealtimeService(IHubContext<CallCenterHub> hubContext, IUserCacheManager userCacheManager)
         {
-            _hubContext= hubContext;
-            _userCacheManager= userCacheManager;
+            _hubContext = hubContext;
+            _userCacheManager = userCacheManager;
         }
 
         /// <summary>
@@ -32,7 +32,7 @@ namespace CallCenter.Api.Realtimes
         {
             var work = _userCacheManager.GetWorkByUser(userId);
             if (string.IsNullOrEmpty(work.SignalRId))
-                throw new UserFriendlyException("无效signalr.connectionId");
+                throw new UserFriendlyException($"无效signalr.connectionId, workId:{work.Id}, userId: {userId}");
             await _hubContext.Clients.Client(work.SignalRId).SendAsync(RealtimeMethods.Ring, dto, cancellationToken);
         }
 
@@ -75,10 +75,10 @@ namespace CallCenter.Api.Realtimes
         /// <param name="count"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        public async Task CallQueueAsync(List<Call> list,CancellationToken cancellationToken)
+        public async Task CallQueueAsync(List<Call> list, CancellationToken cancellationToken)
         {
             var works = _userCacheManager.GetWorks();
-            if (works!=null)
+            if (works != null)
             {
                 var sendlist = works.Where(x => x.SignalRId != null && x.SignalRId != "").Select(x => x.SignalRId).ToList();
                 foreach (var item in sendlist)
@@ -99,7 +99,7 @@ namespace CallCenter.Api.Realtimes
         public async Task AlertAsync(string userId, AlertDto dto, CancellationToken cancellationToken)
         {
             var work = _userCacheManager.GetWorkByUser(userId);
-            if(string.IsNullOrEmpty(work.SignalRId))
+            if (string.IsNullOrEmpty(work.SignalRId))
                 throw new UserFriendlyException("无效signalr.connectionId");
             await _hubContext.Clients.Client(work.SignalRId).SendAsync(RealtimeMethods.Alert, dto, cancellationToken);
         }

+ 193 - 0
src/CallCenter.Api/appsettings.Development.json

@@ -56,6 +56,19 @@
   },
   "WorkTimeSettings": {
     "LineSetting": [
+      {
+        //"NumNo": "12345",
+        "NumNo": "02881145654",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "08dae7d5-4332-40e8-85dd-ad210e40270b",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
       {
         //"NumNo": "12345",
         "NumNo": "3495",
@@ -104,6 +117,186 @@
         "RestCategory": "",
         "WorkToGroup": "1",
         "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12310",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12312",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12313",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12318",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12336",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12338",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12349",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12350",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12351",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12355",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12356",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12363",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "12385",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "96198",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
+      },
+      {
+        "NumNo": "96960",
+        "MorningBegin": "00:00",
+        "MorningEnd": "12:00",
+        "AfterBegin": "12:00",
+        "AfterEnd": "23:59",
+        "WorkDay": [ 1, 2, 3, 4, 5, 6, 0 ],
+        "WorkCategory": "",
+        "RestCategory": "",
+        "WorkToGroup": "1",
+        "RestToGroup": "1"
       }
     ]
   },

+ 2 - 2
src/CallCenter.Application/Handlers/BaseHandler.cs

@@ -108,8 +108,8 @@ namespace CallCenter.Application.Handlers
                             Visitor = new VisitorToGroupQueueVisitor() { Id = model.ConversationId }
                         }, _options.Value.ReceiveKey, _options.Value.Expired, cancellationToken);
 
-                        //处理队列记录
-                        _callCacheManager.AddCallCache(model);
+                        //处理队列记录 TODO
+                        //_callCacheManager.AddCallCache(model);
                         break;
                     case EIvrAnswerType.Out:
                         var phoneNo = ivrAnswer.Content;

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

@@ -47,8 +47,8 @@ namespace CallCenter.Application.Handlers
                 };
                 await _callDetailRepository.AddAsync(detail, cancellationToken);
 
-                //处理排队缓存数据
-                _callCacheManager.RemoveCallCache(model.Id);
+                //处理排队缓存数据 TODO
+                //_callCacheManager.RemoveCallCache(model.Id);
 
                 //调用业务弹屏 通知前端
                 var workModel = _userCacheManager.GetWorkByTel(notification.TelNo);

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

@@ -48,8 +48,8 @@ namespace CallCenter.Application.Handlers
                 };
                 await _callDetailRepository.AddAsync(detail, cancellationToken);
 
-                //处理队列记录
-                _callCacheManager.RemoveCallCache(model.Id);
+                //处理队列记录 TODO
+                //_callCacheManager.RemoveCallCache(model.Id);
 
                 //查询应答分机分机号
                 var callDetailAnswer = await _callDetailRepository.GetAsync(x => x.CallId == model.Id && x.EventName == "ANSWER", true, d => d.CreationTime);

+ 2 - 2
src/CallCenter.Application/Handlers/FlowControl/ByeVisitorOffNotificationHandler.cs

@@ -48,8 +48,8 @@ namespace CallCenter.Application.Handlers
                 };
                 await _callDetailRepository.AddAsync(detail, cancellationToken);
 
-                //处理队列记录
-                _callCacheManager.RemoveCallCache(model.Id);
+                //处理队列记录 TODO
+                //_callCacheManager.RemoveCallCache(model.Id);
 
                 //查询应答分机分机号
                 var callDetailAnswer = await _callDetailRepository.GetAsync(x => x.CallId == model.Id && x.EventName == "ANSWER", true, d => d.CreationTime);

+ 24 - 12
src/CallCenter.Application/Handlers/FlowControl/CdrNotificationHandler.cs

@@ -7,6 +7,7 @@ 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;
@@ -36,7 +37,7 @@ namespace CallCenter.Application.Handlers
         public async Task Handle(CdrNotification notification, CancellationToken cancellationToken)
         {
             var callDetail = await 
-                _callDetailRepository.GetAsync(x => x.OMCallId == notification.CallId, cancellationToken);
+                _callDetailRepository.GetAsync(x => x.OMCallId == notification.CallId,true,x=>x.CreationTime, cancellationToken);
             
             if (callDetail!=null)
             {
@@ -65,12 +66,20 @@ namespace CallCenter.Application.Handlers
                     model.OuterId = notification.OuterId;
 
                 await _callRecordRepository.AddAsync(model,cancellationToken);
-
-                var ishave = await _callDetailRepository.AnyAsync(x => x.EventName == "INCOMING" && x.OMCallId == notification.CallId && x.FromNo == notification.CPN && x.ToNo == notification.CDPN);
-
+                var callModel = await _callRepository.GetAsync(x => x.Id == callDetail.CallId, cancellationToken);
+                var callStr = JsonSerializer.Serialize(callModel);
+                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)
                 {
-                    var callModel = await _callRepository.GetAsync(x => x.Id == callDetail.CallId, cancellationToken);
                     if (callModel != null)
                     {
                         callModel.Duration = double.Parse(model.Duration);
@@ -102,7 +111,15 @@ namespace CallCenter.Application.Handlers
                         callDto.BeginTime = call.CreationTime;
                         callDto.ByeTime = call.CallDetails?.FirstOrDefault(x => x.EventName == "BYE").CreationTime;
                         callDto.TalkTime = call.Duration;
-                        callDto.SoundFileName = model.Recording ?? call.CallDetails?.FirstOrDefault(x => x.EventName == "BYE")?.Recording;
+                        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;
@@ -122,16 +139,11 @@ namespace CallCenter.Application.Handlers
                             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<FwResult>(respContentString);
-                            //成功
-                            if (result.code == 1)
-                            {
-
-                            }
+                            _logger.LogInformation("推送报告结果:" + respContentString);
                         }
                         catch (Exception ex)
                         {

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

@@ -123,8 +123,8 @@ namespace CallCenter.Application.Handlers
                             _options.Value.ReceiveKey, _options.Value.Expired, cancellationToken);
                             model.InGroupTime = DateTime.Now;
                             await _callRepository.UpdateAsync(model, cancellationToken);
-                            //处理队列记录
-                            _callCacheManager.AddCallCache(model);
+                            //处理队列记录 TODO
+                            //_callCacheManager.AddCallCache(model);
                             break;
                         default:
                             break;

+ 1 - 1
src/CallCenter.Application/Handlers/System/BootupNotificationHandler.cs

@@ -41,7 +41,7 @@ namespace CallCenter.Application.Handlers.System
 
                 }
                 //轮循还原设备分机组信息
-                await _deviceManager.AssginConfigGroupAsync(groupItem.No, groupItem.Distribution.ToString(), exts, groupItem.Voice,
+                await _deviceManager.AssginConfigGroupAsync(groupItem.No, groupItem.Distribution, exts, groupItem.Voice,
                     cancellationToken);
             }
 

+ 19 - 19
src/CallCenter.CacheManager/CallQueueManager.cs

@@ -23,26 +23,26 @@ namespace CallCenter.CacheManager
 
         protected override async Task ExecuteAsync(CancellationToken cancellationToken)
         {
-            //work缓存注入
-            var userCacheManager = _serviceScopeFactory.CreateScope().ServiceProvider.GetService<IUserCacheManager>();
-            //消息通知注入
-            var realtimeService = _serviceScopeFactory.CreateScope().ServiceProvider.GetService<IRealtimeService>();
-            //CallQueue缓存注入
-            var callQueueManager = _serviceScopeFactory.CreateScope().ServiceProvider.GetService<ICallCacheManager>();
+            ////work缓存注入
+            //var userCacheManager = _serviceScopeFactory.CreateScope().ServiceProvider.GetService<IUserCacheManager>();
+            ////消息通知注入
+            //var realtimeService = _serviceScopeFactory.CreateScope().ServiceProvider.GetService<IRealtimeService>();
+            ////CallQueue缓存注入
+            //var callQueueManager = _serviceScopeFactory.CreateScope().ServiceProvider.GetService<ICallCacheManager>();
 
-            var time = TimeSpan.FromSeconds(1);
-            while (!cancellationToken.IsCancellationRequested)
-            {
-                //查询当前队列
-                var callList = callQueueManager.GetCallQueueList();
-                if (callList ==null)
-                {
-                    callList = new List<Calls.Call>();
-                }
-                //通知
-                await realtimeService.CallQueueAsync(callList, cancellationToken);
-                await Task.Delay(time, cancellationToken);
-            }
+            //var time = TimeSpan.FromSeconds(1);
+            //while (!cancellationToken.IsCancellationRequested)
+            //{
+            //    //查询当前队列
+            //    var callList = callQueueManager.GetCallQueueList();
+            //    if (callList ==null)
+            //    {
+            //        callList = new List<Calls.Call>();
+            //    }
+            //    //通知
+            //    await realtimeService.CallQueueAsync(callList, cancellationToken);
+            //    await Task.Delay(time, cancellationToken);
+            //}
 
             
         }

+ 71 - 17
src/CallCenter.NewRock/DeviceManager.cs

@@ -18,6 +18,7 @@ using XF.Domain.Dependency;
 using XF.Domain.Exceptions;
 using Group = NewRock.Sdk.Control.Request.Group;
 using CallCenter.Share.Enums;
+using CallCenter.Caches;
 
 namespace CallCenter.NewRock
 {
@@ -27,13 +28,19 @@ namespace CallCenter.NewRock
         private readonly ICallRepository _callRepository;
         private readonly IOptionsSnapshot<DeviceConfigs> _options;
         private readonly IMapper _mapper;
+        private readonly ITelGroupRepository _telGroupRepository;
+        private readonly IUserCacheManager _userCacheManager;
+        private readonly ITelRestRepository _telRestRepository;
 
-        public DeviceManager(INewRockClient newRockClient, IOptionsSnapshot<DeviceConfigs> options, IMapper mapper, ICallRepository callRepository)
+        public DeviceManager(INewRockClient newRockClient, IOptionsSnapshot<DeviceConfigs> options, IMapper mapper, ICallRepository callRepository, ITelGroupRepository telGroupRepository,IUserCacheManager userCacheManager, ITelRestRepository telRestRepository)
         {
             _newRockClient = newRockClient;
             _options = options;
             _mapper = mapper;
             _callRepository = callRepository;
+            _telGroupRepository = telGroupRepository;
+            _userCacheManager = userCacheManager;
+            _telRestRepository = telRestRepository;
         }
 
         #region 查询
@@ -293,7 +300,7 @@ namespace CallCenter.NewRock
         /// <param name="ext"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        public async Task AssginConfigGroupAsync(string groupId, string distribution, List<string> ext, string? voiceFile = "",CancellationToken cancellationToken=default)
+        public async Task AssginConfigGroupAsync(string groupId, EDistribution distribution, List<string> ext, string? voiceFile = "",CancellationToken cancellationToken=default)
         {
             if (!int.TryParse(groupId, out int mId))
                 throw new UserFriendlyException("请输入数字");
@@ -304,9 +311,23 @@ namespace CallCenter.NewRock
             var groupModel = new Group()
             {
                 Id = groupId,
-                Distribution = distribution,
                 Ext = ext,
             };
+            switch (distribution)
+            {
+                case EDistribution.Sequential:
+                    groupModel.Distribution = "sequential";
+                    break;
+                case EDistribution.Group:
+                    groupModel.Distribution = "group";
+                    break;
+                case EDistribution.Circular:
+                    groupModel.Distribution = "circular";
+                    break;
+                default:
+                    break;
+            }
+
             if (!string.IsNullOrEmpty(voiceFile))
                 groupModel.Voicefile = voiceFile;
 
@@ -319,6 +340,7 @@ namespace CallCenter.NewRock
                 cancellationToken);
         }
 
+        
 
         /// <summary>
         /// 更新分机组
@@ -328,7 +350,7 @@ namespace CallCenter.NewRock
         /// <param name="cancellationToken"></param>
         /// <param name="isAdd"></param>
         /// <returns></returns>
-        public async Task ModifyGroupExtAsync(string groupId,string ext,string voicefile="",bool isAdd=true,CancellationToken cancellationToken = default)
+        public async Task ModifyGroupExtAsync(string groupId, EDistribution distribution, string voicefile="", string extId = "",bool isAdd=true,CancellationToken cancellationToken = default)
         {
             if (!int.TryParse(groupId, out int mId))
                 throw new UserFriendlyException("请输入数字");
@@ -336,31 +358,63 @@ namespace CallCenter.NewRock
             if (mId < 1 || mId > 50)
                 throw new UserFriendlyException("分机组只允许在1-50范围内");
 
-            //查询原设备数据
-            var result = await _newRockClient.QueryExtGroup(
-                new QueryExtGroupRequest() { Attribute = "Query", Group = new QueryExtGroup() { Id = groupId } },
+            #region 清除分机组设置
+
+            await _newRockClient.ConfigExtGroup(
+                new AssginConfigGroupRequest() { Attribute = "Assign", Group = new Group() { Id = groupId }, },
                 _options.Value.ReceiveKey,
                 _options.Value.Expired,
                 cancellationToken
-            );
+                );
+
+
+            #endregion
+
+
+            var list = await _telGroupRepository.QueryExtAsync(d =>d.No== groupId, d => d.Includes(x => x.Tels));
+
+            List<string> exts = new List<string>();
+            foreach (var ext in list[0].Tels)
+            {
+                var iswork = await _userCacheManager.IsWorkingByTelAsync(ext.No, cancellationToken);
+                if (iswork)
+                    exts.Add(ext.No);
+
+            }
+
+            //查询所有正在休息的分机
+            List<string> restexts = (await _telRestRepository.QueryAsync(x => x.EndTime == null)).Select(x=>x.TelNo).ToList();
+            if (restexts!=null && restexts.Count>0)
+            {
+                foreach (var item in restexts)
+                {
+                    exts.Remove(item);
+                }
+            }
+
+
             //更新
-            var exts = result.Group[0].Ext;
             var groupModel = new Group()
             {
                 Id = groupId,
                 Voicefile = voicefile
             };
-
-            if (isAdd)
-            {
-                exts.Add(new QueryExtGroupExt(){ Id = ext });
-            }
-            else
+            switch (distribution)
             {
-                exts.Remove(exts.First(x=>x.Id == ext));
+                case EDistribution.Sequential:
+                    groupModel.Distribution = "sequential";
+                    break;
+                case EDistribution.Group:
+                    groupModel.Distribution = "group";
+                    break;
+                case EDistribution.Circular:
+                    groupModel.Distribution = "circular";
+                    break;
+                default:
+                    break;
             }
 
-            groupModel.Ext = exts.Select(x=>x.Id).ToList();
+            groupModel.Ext = exts;
             await _newRockClient.ConfigExtGroup(
                 new AssginConfigGroupRequest() { Attribute = "Assign", Group = groupModel, },
                 _options.Value.ReceiveKey,

+ 3 - 2
src/CallCenter/Devices/IDeviceManager.cs

@@ -5,6 +5,7 @@ using System.Text;
 using System.Threading.Tasks;
 using CallCenter.Calls;
 using CallCenter.Share.Dtos;
+using CallCenter.Share.Enums;
 using CallCenter.Tels;
 using Org.BouncyCastle.Operators;
 using SqlSugar;
@@ -102,7 +103,7 @@ namespace CallCenter.Devices
         /// <param name="ext"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        Task AssginConfigGroupAsync(string groupId, string distribution, List<string> ext, string? voiceFile = "", CancellationToken cancellationToken = default);
+        Task AssginConfigGroupAsync(string groupId, EDistribution distribution, List<string> ext, string? voiceFile = "", CancellationToken cancellationToken = default);
 
         /// <summary>
         /// 更新分机组
@@ -112,7 +113,7 @@ namespace CallCenter.Devices
         /// <param name="cancellationToken"></param>
         /// <param name="isAdd"></param>
         /// <returns></returns>
-        Task ModifyGroupExtAsync(string groupId, string ext, string voicefile = "",bool isAdd= true, CancellationToken cancellationToken = default);
+        Task ModifyGroupExtAsync(string groupId, EDistribution distribution, string voicefile = "", string extId = "", bool isAdd= true, CancellationToken cancellationToken = default);
         #endregion
 
         #region 通话控制

+ 1 - 1
src/CallCenter/Tels/ITelDomainService.cs

@@ -52,7 +52,7 @@ namespace CallCenter.Tels
         /// <param name="telId"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        Task<TelRest> UnRestAsync(string telId, CancellationToken cancellationToken);
+        Task<TelRest> UnRestAsync(string userId,string telId, CancellationToken cancellationToken);
 
         /// <summary>
         /// 保持通话

+ 37 - 6
src/CallCenter/Tels/TelDomainService.cs

@@ -1,4 +1,5 @@
-using CallCenter.Devices;
+using CallCenter.Caches;
+using CallCenter.Devices;
 using CallCenter.Share.Dtos;
 using CallCenter.Users;
 using MapsterMapper;
@@ -12,15 +13,21 @@ public class TelDomainService : ITelDomainService, IScopeDependency
     private readonly IDeviceManager _deviceManager;
     private readonly ITelRepository _telRepository;
     private readonly ITelRestRepository _telRestRepository;
+    private readonly ITelCacheManager _telCacheManager;
+    private readonly IUserRepository _userRepository;
 
     public TelDomainService(
         IDeviceManager deviceManager,
         ITelRepository telRepository,
-        ITelRestRepository telRestRepository)
+        ITelRestRepository telRestRepository,
+        ITelCacheManager telCacheManager,
+        IUserRepository userRepository)
     {
         _deviceManager = deviceManager;
         _telRepository = telRepository;
         _telRestRepository = telRestRepository;
+        _telCacheManager = telCacheManager;
+        _userRepository = userRepository;
     }
 
 
@@ -51,9 +58,19 @@ public class TelDomainService : ITelDomainService, IScopeDependency
         var isResting = await _telRepository.IsRestingAsync(currentWork.TelNo, cancellationToken);
         if (!isResting)
         {
-            await _deviceManager.TelRestAsync(currentWork.TelNo, cancellationToken);
+            //await _deviceManager.TelRestAsync(currentWork.TelNo, cancellationToken);
+            
+            var tel = _telCacheManager.GetTel(currentWork.TelNo);
             await _telRestRepository.AddAsync(new TelRest(currentWork.TelId, currentWork.TelNo, currentWork.UserId, currentWork.UserName),
                 cancellationToken);
+            //暂时移除分机组
+            #region 处理设备
+            //更新分机组
+            foreach (var group in tel.Groups)
+            {
+                await _deviceManager.ModifyGroupExtAsync(group.No, group.Distribution, group.Voice,tel.No, true, cancellationToken);
+            }
+            #endregion
         }
     }
 
@@ -63,17 +80,31 @@ public class TelDomainService : ITelDomainService, IScopeDependency
     /// <param name="telId"></param>
     /// <param name="cancellationToken"></param>
     /// <returns></returns>
-    public async Task<TelRest> UnRestAsync(string telId, CancellationToken cancellationToken)
+    public async Task<TelRest> UnRestAsync(string userId, string telId, CancellationToken cancellationToken)
     {
+        var user = await _userRepository.GetAsync(userId, cancellationToken);
         var tel = await _telRepository.GetAsync(telId, cancellationToken);
-        if (tel is null)
+        var telCache = _telCacheManager.GetTel(tel.No);
+        if (telCache is null)
             throw new UserFriendlyException("无效分机编号");
-        await _deviceManager.TelEndRestAsync(tel.No, cancellationToken);
+        //await _deviceManager.TelEndRestAsync(tel.No, cancellationToken);
+        
         var restingTel = await _telRestRepository.GetAsync(d => d.TelId == telId && !d.EndTime.HasValue, cancellationToken);
         if (restingTel is null)
             throw new UserFriendlyException("未查询到分机休息信息");
         restingTel.EndRest();
         await _telRestRepository.UpdateAsync(restingTel, cancellationToken);
+
+        //将分机加入到分机组
+        #region 处理设备
+
+        //更新分机组
+        foreach (var group in telCache.Groups)
+        {
+            await _deviceManager.ModifyGroupExtAsync(group.No, group.Distribution, group.Voice, "", true, cancellationToken);
+        }
+
+        #endregion
         return restingTel;
     }
 

+ 12 - 6
src/CallCenter/Users/UserDomainService.cs

@@ -19,6 +19,7 @@ namespace CallCenter.Users
         private readonly ITelCacheManager _telCacheManager;
         private readonly ITypedCache<Work> _cacheWork;
         private readonly IMapper _mapper;
+        private readonly ITelRepository _telRepository;
 
         public UserDomainService(
             IUserRepository userRepository,
@@ -26,7 +27,7 @@ namespace CallCenter.Users
             IDeviceManager deviceManager,
             ITypedCache<Work> cacheWork,
             IUserCacheManager userCacheManager,
-            IMapper mapper, ITelCacheManager telCacheManager)
+            IMapper mapper, ITelCacheManager telCacheManager, ITelRepository telRepository)
         {
             _userRepository = userRepository;
             _workRepository = workRepository;
@@ -35,6 +36,7 @@ namespace CallCenter.Users
             _cacheWork = cacheWork;
             _mapper = mapper;
             _telCacheManager = telCacheManager;
+            _telRepository = telRepository;
         }
 
         /// <summary>
@@ -70,7 +72,7 @@ namespace CallCenter.Users
             //更新分机组
             foreach (var group in tel.Groups)
             {
-                await _deviceManager.ModifyGroupExtAsync(group.No,tel.No,group.Voice,true, cancellationToken);
+                await _deviceManager.ModifyGroupExtAsync(group.No,group.Distribution, group.Voice,"",true, cancellationToken);
             }
         }
 
@@ -82,8 +84,12 @@ namespace CallCenter.Users
         /// <returns></returns>
         public async Task<WorkDto?> OffDutyAsync(string userId, CancellationToken cancellationToken)
         {
+            
             var work = _userCacheManager.GetWorkByUser(userId);
             var tel = _telCacheManager.GetTel(work.TelNo);
+            var isResting = await _telRepository.IsRestingAsync(work.TelNo, cancellationToken);
+            if (isResting)
+                throw new UserFriendlyException("分机正在休息,不能签出");
             work.OffDuty();
             await _workRepository.UpdateAsync(work, cancellationToken);
             await _deviceManager.UpdateStaffNoAsync(work.TelNo, string.Empty, tel.LineId, cancellationToken);
@@ -93,10 +99,10 @@ namespace CallCenter.Users
             //更新work缓存
             _userCacheManager.RemoveWorksCache(work.Id);
 
-            //foreach (var group in tel.Groups)
-            //{
-            //    await _deviceManager.ModifyGroupExtAsync(group.No, tel.No, group.Voice, false, cancellationToken);
-            //}
+            foreach (var group in tel.Groups)
+            {
+                await _deviceManager.ModifyGroupExtAsync(group.No,group.Distribution ,group.Voice,"", false, cancellationToken);
+            }
 
             return _mapper.Map<WorkDto>(work);
         }