Sfoglia il codice sorgente

Merge branch 'master' of http://git.fwt.com/Hotline/hotline

xf 2 anni fa
parent
commit
6e89cb1df1

+ 20 - 5
src/Hotline.Api/Controllers/PbxController.cs

@@ -1,4 +1,6 @@
-using Hotline.Caches;
+using Hotline.Application.FlowEngine;
+using Hotline.CacheManager;
+using Hotline.Caches;
 using Hotline.CallCenter.Calls;
 using Hotline.CallCenter.Devices;
 using Hotline.CallCenter.Ivrs;
@@ -8,6 +10,7 @@ using Hotline.Permissions;
 using Hotline.Repository.SqlSugar.CallCenter;
 using Hotline.Settings;
 using Hotline.Share.Dtos.CallCenter;
+using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.Trunk;
 using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Requests;
@@ -18,6 +21,7 @@ using Microsoft.AspNetCore.Mvc;
 using SqlSugar;
 using XF.Domain.Authentications;
 using XF.Domain.Cache;
+using XF.Domain.Constants;
 using XF.Domain.Exceptions;
 using XF.Utility.EnumExtensions;
 
@@ -41,6 +45,8 @@ namespace Hotline.Api.Controllers
         private readonly ICallRepository _callRepository;
         private readonly ITrunkIvrManagerRepository _trunkIvrManagerRepository;
         private readonly IIvrCategoryRepository _ivrCategoryRepository;
+        private readonly IWorkflowApplication _workflowApplication;
+        private readonly ISystemSettingCacheManager _systemSettingCacheManager;
 
         public PbxController(
             ITelRepository telRepository,
@@ -55,7 +61,9 @@ namespace Hotline.Api.Controllers
             ISessionContext sessionContext,
             ICallRepository callRepository,
             ITrunkIvrManagerRepository trunkIvrManagerRepository,
-            IIvrCategoryRepository ivrCategoryRepository)
+            IIvrCategoryRepository ivrCategoryRepository,
+            IWorkflowApplication workflowApplication,
+            ISystemSettingCacheManager systemSettingCacheManager)
         {
             _telRepository = telRepository;
             _telDomainService = telDomainService;
@@ -70,6 +78,8 @@ namespace Hotline.Api.Controllers
             _callRepository = callRepository;
             _trunkIvrManagerRepository = trunkIvrManagerRepository;
             _ivrCategoryRepository = ivrCategoryRepository;
+            _workflowApplication = workflowApplication;
+            _systemSettingCacheManager = systemSettingCacheManager;
         }
 
         #region 话机
@@ -204,13 +214,18 @@ namespace Hotline.Api.Controllers
         /// </summary>
         /// <returns></returns>
         [Permission(EPermission.Rest)]
-        [HttpPut("rest")]
-        public async Task Rest()
+        [HttpPost("rest")]
+        public async Task Rest([FromBody] StartRestDto dto)
         {
             var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
             if (work is null)
                 throw UserFriendlyException.SameMessage("当前坐席暂未进行工作");
-            await _telDomainService.RestAsync(work, HttpContext.RequestAborted);
+            bool isApply = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.RestApproval).SettingValue);
+            string id = await _telDomainService.RestAsync(work,dto.Reason,isApply, HttpContext.RequestAborted);
+            
+            var startworkflow = _mapper.Map<StartWorkflowDto>(dto);
+            if (isApply)
+                await _workflowApplication.StartWorkflowAsync(dto, id, HttpContext.RequestAborted);
         }
 
         /// <summary>

+ 1 - 1
src/Hotline.Api/Controllers/SysController.cs

@@ -276,7 +276,7 @@ namespace Hotline.Api.Controllers
         [HttpGet("dictdata-type")]
         public async Task<List<SysDicData>> GetSysDicData([FromQuery] GetSysDicDataDto dto)
         {
-            return await _sysDicDataRepository.Queryable().Where(x => x.DicTypeId == dto.typeid).WhereIF(!string.IsNullOrEmpty(dto.datavalue),x=>x.DicDataValue.Contains(dto.datavalue)).ToTreeAsync(x=>x.children,x=>x.ParentId,"");
+            return await _sysDicDataRepository.Queryable().Where(x => x.DicTypeId == dto.typeid).WhereIF(!string.IsNullOrEmpty(dto.datavalue),x=>x.DicDataValue.Contains(dto.datavalue)).ToTreeAsync(x=>x.Children,x=>x.ParentId,"");
         }
 
         /// <summary>

+ 1 - 0
src/Hotline.Api/Realtimes/RealtimeMethods.cs

@@ -5,6 +5,7 @@
         public static string Ring = "Ring";
         public static string Answered = "Answered";
         public static string Bye= "Bye";
+        public static string RestApplyPass = "RestApplyPass";
     }
 }
     

+ 15 - 0
src/Hotline.Api/Realtimes/RealtimeService.cs

@@ -65,4 +65,19 @@ public class RealtimeService : IRealtimeService, IScopeDependency
         await _hubContext.Clients.Client(work.SignalRId).SendAsync(RealtimeMethods.Bye, dto, cancellationToken);
     }
 
+    /// <summary>
+    /// 小休审核通过后通知前端
+    /// </summary>
+    /// <param name="userId"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    /// <exception cref="UserFriendlyException"></exception>
+    public async Task RestApplyPassAsync(string userId,CancellationToken cancellationToken)
+    {
+        var work = _userCacheManager.GetWorkByUser(userId);
+        if (string.IsNullOrEmpty(work.SignalRId))
+            throw new UserFriendlyException("无效signalr.connectionId");
+        await _hubContext.Clients.Client(work.SignalRId).SendAsync(RealtimeMethods.RestApplyPass, cancellationToken);
+    }
+
 }

+ 18 - 3
src/Hotline.Application/Handlers/FlowEngine/EndWorkflowHandler.cs

@@ -1,17 +1,32 @@
 using Hotline.FlowEngine.Notifies;
+using Hotline.Settings;
+using Hotline.Share.Enums.Order;
 using MediatR;
 
 namespace Hotline.Application.Handlers.FlowEngine;
 
 public class EndWorkflowHandler : INotificationHandler<EndWorkflowNotify>
 {
+
+    public EndWorkflowHandler()
+    {
+
+    }
+
     /// <summary>Handles a notification</summary>
     /// <param name="notification">The notification</param>
     /// <param name="cancellationToken">Cancellation token</param>
     public async Task Handle(EndWorkflowNotify notification, CancellationToken cancellationToken)
     {
-        //todo 知识审批收到此消息表示审批通过
-        //todo order归档
-        throw new NotImplementedException();
+        var workflow = notification.Workflow;
+
+        switch (workflow.ModuleCode)
+        {
+            case WorkflowModuleConsts.TelRestApply:
+                //TODO 审核通过
+                //notification.Workflow.ExternalId;
+                break;
+
+        }
     }
 }

+ 32 - 0
src/Hotline.CacheManager/SysDicDataCacheManager.cs

@@ -0,0 +1,32 @@
+using Hotline.Caches;
+using Hotline.Settings;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Cache;
+
+namespace Hotline.CacheManager
+{
+    public class SysDicDataCacheManager : ISysDicDataCacheManager
+    {
+        private readonly ISysDicDataRepository _sysDicDataRepository;
+        private readonly ITypedCache<IReadOnlyList<SysDicData>> _cacheSysDicData;
+
+        public SysDicDataCacheManager(ISysDicDataRepository sysDicDataRepository,ITypedCache<IReadOnlyList<SysDicData>> cacheSysDicData)
+        {
+            _sysDicDataRepository = sysDicDataRepository;
+            _cacheSysDicData = cacheSysDicData;
+        }
+
+        public IReadOnlyList<SysDicData> GetSysDicDataCache(string code)
+        {
+            var sysDicDataList = _cacheSysDicData.GetOrAdd(code, k =>
+            {
+                return _sysDicDataRepository.Queryable().Where(x => x.DicTypeCode == code).ToTreeAsync(x => x.Children, it => it.ParentId, "").GetAwaiter().GetResult();
+            });
+            return sysDicDataList;
+        }
+    }
+}

+ 11 - 1
src/Hotline.Share/Dtos/CallCenter/TelRestDto.cs

@@ -1,5 +1,15 @@
-namespace Hotline.Share.Dtos.CallCenter
+using Hotline.Share.Dtos.FlowEngine;
+
+namespace Hotline.Share.Dtos.CallCenter
 {
+    public class StartRestDto: StartWorkflowDto
+    {
+        /// <summary>
+        /// 小休原因
+        /// </summary>
+        public string Reason { get; set; }
+    }
+
     public record TelRestDto
     {
         /// <summary>

+ 23 - 0
src/Hotline.Share/Enums/Order/ERestApplyStatus.cs

@@ -0,0 +1,23 @@
+
+namespace Hotline.Share.Enums.Order
+{
+    public enum ERestApplyStatus
+    {
+        /// <summary>
+        /// 待审核
+        /// </summary>
+        NoAudit = 0,
+        /// <summary>
+        /// 休息中
+        /// </summary>
+        Resting = 1,
+        /// <summary>
+        /// 已终止
+        /// </summary>
+        Shoping = 2,
+        /// <summary>
+        /// 已结束
+        /// </summary>
+        Ending = 3,
+    }
+}

+ 14 - 0
src/Hotline/Caches/ISysDicDataCacheManager.cs

@@ -0,0 +1,14 @@
+using Hotline.Settings;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Caches
+{
+    public interface ISysDicDataCacheManager
+    {
+        IReadOnlyList<SysDicData> GetSysDicDataCache(string code);
+    }
+}

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

@@ -44,7 +44,15 @@ namespace Hotline.CallCenter.Tels
         /// <param name="currentWork"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        Task RestAsync(Work currentWork, CancellationToken cancellationToken);
+        Task<string> RestAsync(Work currentWork,string reason,bool isApply, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// 分机小休审批通过
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        Task RestApplyPass(string id, CancellationToken cancellationToken);
 
         /// <summary>
         /// 分机结束休息

+ 32 - 4
src/Hotline/CallCenter/Tels/TelDomainService.cs

@@ -1,5 +1,9 @@
-using Hotline.CallCenter.Devices;
+using Hotline.Caches;
+using Hotline.CallCenter.Devices;
+using Hotline.Realtimes;
 using Hotline.Users;
+using System.Reflection;
+using XF.Domain.Constants;
 using XF.Domain.Dependency;
 using XF.Domain.Exceptions;
 
@@ -11,17 +15,20 @@ public class TelDomainService : ITelDomainService, IScopeDependency
     private readonly ITelRepository _telRepository;
     private readonly ITelRestRepository _telRestRepository;
     private readonly ITelHoldRepository _telHoldRepository;
+    private readonly IRealtimeService _realtimeService;
 
     public TelDomainService(
         IDeviceManager deviceManager,
         ITelRepository telRepository,
         ITelRestRepository telRestRepository,
-        ITelHoldRepository telHoldRepository)
+        ITelHoldRepository telHoldRepository,
+        IRealtimeService realtimeService)
     {
         _deviceManager = deviceManager;
         _telRepository = telRepository;
         _telRestRepository = telRestRepository;
         _telHoldRepository = telHoldRepository;
+        _realtimeService = realtimeService;
     }
 
 
@@ -47,15 +54,36 @@ public class TelDomainService : ITelDomainService, IScopeDependency
     /// <param name="currentWork"></param>
     /// <param name="cancellationToken"></param>
     /// <returns></returns>
-    public async Task RestAsync(Work currentWork, CancellationToken cancellationToken)
+    public async Task<string> RestAsync(Work currentWork,string reason,bool isApply, CancellationToken cancellationToken)
     {
         var isResting = await _telRepository.IsRestingAsync(currentWork.TelNo, cancellationToken);
         if (!isResting)
         {
             await _deviceManager.TelRestAsync(currentWork.TelNo, cancellationToken);
-            await _telRestRepository.AddAsync(new TelRest(currentWork.TelId, currentWork.TelNo, currentWork.UserId, currentWork.UserName),
+            
+            return await _telRestRepository.AddAsync(new TelRest(currentWork.TelId, currentWork.TelNo, currentWork.UserId, currentWork.UserName,reason, isApply),
                 cancellationToken);
         }
+        throw new UserFriendlyException("当前坐席正在休息");
+    }
+
+    /// <summary>
+    /// 分机审批通过
+    /// </summary>
+    /// <param name="id"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task RestApplyPass(string id, CancellationToken cancellationToken)
+    {
+        var telrest = await _telRestRepository.GetAsync(id, cancellationToken);
+        if(telrest!=null)
+        {
+            telrest.ApplyStatus = Share.Enums.Order.ERestApplyStatus.Resting;
+            telrest.StartTime = DateTime.Now;
+            await _telRestRepository.UpdateAsync(telrest, cancellationToken);
+            //通知前端休息通过
+            await _realtimeService.RestApplyPassAsync(telrest.UserId, cancellationToken);
+        }
     }
 
     /// <summary>

+ 26 - 5
src/Hotline/CallCenter/Tels/TelRest.cs

@@ -1,4 +1,5 @@
 using System.ComponentModel;
+using Hotline.Share.Enums.Order;
 using SqlSugar;
 using XF.Domain.Entities;
 using XF.Domain.Repository;
@@ -6,7 +7,7 @@ using XF.Domain.Repository;
 namespace Hotline.CallCenter.Tels
 {
     [Description("分机休息记录")]
-    public class TelRest : CreationModificationEntity
+    public class TelRest : WorkflowEntity//, CreationModificationEntity
     {
         /// <summary>
         /// 分机id
@@ -33,7 +34,7 @@ namespace Hotline.CallCenter.Tels
         /// 开始休息时间
         /// </summary>
         [SugarColumn(ColumnDescription = "开始休息时间")]
-        public DateTime StartTime { get; init; } = DateTime.Now;
+        public DateTime? StartTime { get; set; }
 
         /// <summary>
         /// 结束休息时间
@@ -47,20 +48,40 @@ namespace Hotline.CallCenter.Tels
         [SugarColumn(ColumnDescription = "休息时长(单位:秒)")]
         public double RestDuration { get; private set; }
 
+        public string Reason { get; set; }
+        /// <summary>
+        /// 审核状态
+        /// </summary>
+        public ERestApplyStatus ApplyStatus { get; set; }
+
         public TelRest()
         {
 
         }
 
-        public TelRest(string telId, string telNo, string userId, string userName)
+        public TelRest(string telId, string telNo, string userId, string userName,string reason,bool isApply)
         {
-            TelId = telId; TelNo = telNo; UserId = userId; UserName = userName;
+            TelId = telId; TelNo = telNo; UserId = userId; UserName = userName; Reason = reason;
+
+            if(isApply)
+            {
+                ApplyStatus = ERestApplyStatus.NoAudit;
+            }
+            else
+            {
+                ApplyStatus = ERestApplyStatus.Resting;
+                StartTime = DateTime.Now;
+            }
         }
 
+
+        
+
+
         public void EndRest()
         {
             EndTime = DateTime.Now;
-            RestDuration = (EndTime.Value - StartTime).TotalSeconds;
+            RestDuration = (EndTime.Value - StartTime.Value).TotalSeconds;
         }
     }
 }

+ 0 - 1
src/Hotline/CallCenter/Tels/TelRestApply.cs

@@ -9,6 +9,5 @@ namespace Hotline.CallCenter.Tels
 {
     public class TelRestApply: PositionWorkflowEntity
     {
-
     }
 }

+ 2 - 0
src/Hotline/Realtimes/IRealtimeService.cs

@@ -9,5 +9,7 @@ namespace Hotline.Realtimes
         Task AnsweredAsync(string userId, AnsweredDto dto, CancellationToken cancellationToken);
 
         Task ByeAsync(string userId, ByeDto dto, CancellationToken cancellationToken);
+
+        Task RestApplyPassAsync(string userId, CancellationToken cancellationToken);
     }
 }

+ 1 - 1
src/Hotline/Settings/SysDicData.cs

@@ -34,6 +34,6 @@ namespace Hotline.Settings
         public string? ParentId { get; set; }
 
         [SugarColumn(IsIgnore = true)]
-        public List<SysDicData> children { get; set; }
+        public List<SysDicData> Children { get; set; }
     }
 }

+ 6 - 0
src/Hotline/Settings/WorkflowModule.cs

@@ -23,6 +23,7 @@ public class WorkflowModule
         {
             { WorkflowModuleConsts.Order, "工单办理" },
             { WorkflowModuleConsts.KnowledgeAdd, "新增知识审批" },
+            { WorkflowModuleConsts.TelRestApply,"分机小休申请" },
         };
 }
 
@@ -37,4 +38,9 @@ public class WorkflowModuleConsts
     /// 新增知识审批
     /// </summary>
     public const string KnowledgeAdd = "KnowledgeAdd";
+
+    /// <summary>
+    /// 分机小休申请
+    /// </summary>
+    public const string TelRestApply = "TelRestApply";
 }