Quellcode durchsuchen

完成话务统计泸州和自贡

qinchaoyue vor 6 Monaten
Ursprung
Commit
587e09179c
22 geänderte Dateien mit 252 neuen und 178 gelöschten Zeilen
  1. 34 68
      src/Hotline.Api/Controllers/Bi/BiCallController.cs
  2. 1 1
      src/Hotline.Application.Tests/Application/YiBinCallReportApplicationTest.cs
  3. 1 1
      src/Hotline.Application.Tests/Application/ZiGongCallReportApplicationTest.cs
  4. 28 0
      src/Hotline.Application/ExportExcel/ExportApplication.cs
  5. 4 1
      src/Hotline.Application/ExportExcel/IExportApplication.cs
  6. 23 10
      src/Hotline.Application/StatisticalReport/CallReport/CallReportApplicationBase.cs
  7. 12 3
      src/Hotline.Application/StatisticalReport/CallReport/YiBinCallReportApplication.cs
  8. 0 38
      src/Hotline.Application/StatisticalReport/ExportApplication.cs
  9. 2 0
      src/Hotline.Application/StatisticalReport/ICallReportApplication.cs
  10. 0 14
      src/Hotline.Application/StatisticalReport/IExportApplication.cs
  11. 12 0
      src/Hotline.Application/Systems/BaseDataApplication.cs
  12. 60 0
      src/Hotline.Repository.SqlSugar/CallCenter/CallNativeRepository.cs
  13. 16 16
      src/Hotline.Repository.SqlSugar/CallCenter/TrCallRecordRepository.cs
  14. 42 9
      src/Hotline.Share/Dtos/CallCenter/BiQueryCallsDto.cs
  15. 0 8
      src/Hotline.Share/Dtos/TrCallCenter/TrTelDao.cs
  16. 4 4
      src/Hotline.Share/Requests/PagedKeywordRequest.cs
  17. 1 0
      src/Hotline/Caching/Interfaces/ISystemSettingCacheManager.cs
  18. 2 0
      src/Hotline/Caching/Services/SystemSettingCacheManager.cs
  19. 5 0
      src/Hotline/CallCenter/Calls/CallNative.cs
  20. 2 0
      src/Hotline/CallCenter/Calls/ICallNativeRepository.cs
  21. 2 4
      src/Hotline/CallCenter/Calls/ITrCallRecordRepository.cs
  22. 1 1
      src/Hotline/Settings/SettingConstants.cs

+ 34 - 68
src/Hotline.Api/Controllers/Bi/BiCallController.cs

@@ -1,25 +1,21 @@
-using Hotline.Application.StatisticalReport;
+using Hotline.Application.ExportExcel;
+using Hotline.Application.StatisticalReport;
+using Hotline.Application.Systems;
 using Hotline.Caching.Interfaces;
 using Hotline.CallCenter.Calls;
 using Hotline.CallCenter.Tels;
-using Hotline.Repository.SqlSugar.Extensions;
-using Hotline.Settings;
 using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.TrCallCenter;
-using Hotline.Share.Enums.CallCenter;
-using Hotline.Share.Enums.User;
 using Hotline.Share.Requests;
 using Hotline.Tools;
 using Hotline.Users;
 using MapsterMapper;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
-using NPOI.SS.Formula.Functions;
 using SqlSugar;
 using System.Data;
-using XF.Domain.Exceptions;
 using XF.Domain.Repository;
 
 namespace Hotline.Api.Controllers.Bi;
@@ -30,6 +26,7 @@ namespace Hotline.Api.Controllers.Bi;
 public class BiCallController : BaseController
 {
     private readonly IRepository<TrCallRecord> _trCallRecordRepository;
+    private readonly BaseDataApplication _baseDataApplication;
     private readonly IRepository<User> _userRepository;
     private readonly IRepository<TelRest> _telRestRepository;
     private readonly IMapper _mapper;
@@ -50,7 +47,8 @@ public class BiCallController : BaseController
         ISystemDicDataCacheManager sysDicDataCacheManager,
         IRepository<Work> workRepository,
         ICallReportApplication callReportApplication,
-        IExportApplication exportApplication)
+        IExportApplication exportApplication,
+        BaseDataApplication baseDataApplication)
     {
         _trCallRecordRepository = trCallRecordRepository;
         _userRepository = userRepository;
@@ -61,6 +59,7 @@ public class BiCallController : BaseController
         _sysDicDataCacheManager = sysDicDataCacheManager;
         _callReportApplication = callReportApplication;
         _exportApplication = exportApplication;
+        _baseDataApplication = baseDataApplication;
     }
 
     /// <summary>
@@ -71,7 +70,7 @@ public class BiCallController : BaseController
     [HttpGet("calls")]
     [AllowAnonymous]
     public async Task<List<BiCallDto>> QueryCallsAsync([FromQuery] BiQueryCallsDto dto)
-        =>  await _callReportApplication.QueryCallsAsync(dto, HttpContext.RequestAborted);
+        => await _callReportApplication.QueryCallsAsync(dto, HttpContext.RequestAborted);
 
     /// <summary>
     /// 话务统计分析---导出
@@ -85,7 +84,7 @@ public class BiCallController : BaseController
             await _exportApplication.FittingAsync(
                 dto,
                 await _callReportApplication.QueryCallsAsync(dto.QueryDto, HttpContext.RequestAborted),
-                list => 
+                list =>
                 {
                     list.Add(new BiCallDto()
                     {
@@ -142,7 +141,8 @@ public class BiCallController : BaseController
             await _exportApplication.FittingAsync(
                 dto,
                 await _callReportApplication.QueryCallsDetailAsync(dto.QueryDto),
-                items => { 
+                items =>
+                {
                     var total = new QueryCallsDetailDto
                     {
                         Date = "合计",
@@ -161,7 +161,7 @@ public class BiCallController : BaseController
                         OutConnectionQuantity = items.Sum(p => p.OutConnectionQuantity)
                     };
                     items.Add(total);
-                    }
+                }
                 )
             , "话务日期明细数据");
 
@@ -214,9 +214,9 @@ public class BiCallController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpGet("query_calls_hour_detail_list")]
-    public async Task<TotalDataList<QueryCallsDetailDto>> QueryCallsHourDetailListAsync([FromQuery] BiQueryCallsDto dto)
+    public async Task<TotalList<QueryCallsDetailDto>> QueryCallsHourDetailListAsync([FromQuery] BiQueryCallsDto dto)
     {
-        var items =  await _callReportApplication.QueryCallsHourDetailAsync(dto, HttpContext.RequestAborted);
+        var items = await _callReportApplication.QueryCallsHourDetailAsync(dto, HttpContext.RequestAborted);
         var total = new QueryCallsDetailDto
         {
             Date = "",
@@ -235,7 +235,7 @@ public class BiCallController : BaseController
             OutConnectionQuantity = items.Sum(p => p.OutConnectionQuantity)
         };
 
-        return new TotalDataList<QueryCallsDetailDto>(items, total);
+        return new TotalList<QueryCallsDetailDto>(items, total);
 
     }
 
@@ -248,10 +248,10 @@ public class BiCallController : BaseController
     public async Task<FileStreamResult> QueryCallsHourDetailListExportAsync([FromBody] ExportExcelDto<BiQueryCallsDto> dto)
         => ExcelStreamResult(
             await _exportApplication.FittingAsync(
-                dto, 
+                dto,
                 await _callReportApplication.QueryCallsHourDetailAsync(dto.QueryDto, HttpContext.RequestAborted),
-                items => 
-                { 
+                items =>
+                {
                     var total = new QueryCallsDetailDto
                     {
                         Date = "",
@@ -286,14 +286,14 @@ public class BiCallController : BaseController
             await _exportApplication.FittingAsync(
                 dto,
                 await _callReportApplication.QuerySeatCallAsync(dto.QueryDto, HttpContext.RequestAborted),
-                list => 
+                list =>
                 {
                     list.Add(new BiSeatCallsDto()
                     {
                         Name = "合计",
                         InTotal = list.Sum(p => p.InTotal),
                         InAnswered = list.Sum(p => p.InAnswered),
-                    InHangupImmediate = list.Sum(p => p.InHangupImmediate),
+                        InHangupImmediate = list.Sum(p => p.InHangupImmediate),
                         InHanguped = list.Sum(m => m.InHanguped),
                         OutDurationAvg = list.Sum(m => m.OutDurationAvg),
                         InAvailableAnswer = list.Sum(m => m.InAvailableAnswer),
@@ -380,7 +380,7 @@ public class BiCallController : BaseController
             await _exportApplication.FittingAsync(
                 dto,
                 await _callReportApplication.GetCallHourListAsync(dto.QueryDto, HttpContext.RequestAborted),
-                list => 
+                list =>
                 {
                     list.Add(new TrCallHourDto()
                     {
@@ -400,17 +400,8 @@ public class BiCallController : BaseController
     /// </summary>
     /// <returns></returns>
     [HttpGet("hourcall_list")]
-    public async Task<object> QueryCallList([FromQuery] DateTime StartTime, DateTime? EndTime, string type, string source, TimeSpan? startHourTo, int pageIndex, int pageSize)
-    {
-        if(!EndTime.HasValue)
-            throw UserFriendlyException.SameMessage("请选择时间!");
-        //获取配置
-        int noConnectByeTimes = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.NoConnectByeTimes)?.SettingValue[0]);
-        int effectiveTimes = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.EffectiveTimes)?.SettingValue[0]);
-        int connectByeTimes = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.ConnectByeTimes)?.SettingValue[0]);
-        var list = await _trCallRecordRepositoryEx.GetCallList(StartTime, EndTime, noConnectByeTimes, effectiveTimes, connectByeTimes, type, source, startHourTo, pageIndex, pageSize);
-        return list;
-    }
+    public async Task<object> QueryCallList([FromQuery] QueryCallListDto dto)
+        => await _callReportApplication.GetCallListAsync(dto, HttpContext.RequestAborted);
 
     /// <summary>
     /// 通话时段统计明细获取基本信息
@@ -419,14 +410,10 @@ public class BiCallController : BaseController
     /// <returns></returns>
     [HttpGet("hourcall_list_base")]
     public async Task<object> ReTransactBaseData()
-    {
-        var rsp = new
-        {
-            CallForwardingSource = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.CallForwardingSource),
-            CallForwardingType = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.CallForwardingType),
-        };
-        return rsp;
-    }
+        => _baseDataApplication
+        .CallForwardingType()
+        .CallForwardingSource()
+        .Build();
 
     /// <summary>
     /// 热线号码统计
@@ -437,15 +424,7 @@ public class BiCallController : BaseController
     [AllowAnonymous]
     [HttpGet("gateway-query")]
     public async Task<List<CallHotLineDto>> QueryGateWay([FromQuery] BiQueryGateWayDto dto)
-    {
-        //获取配置
-        int noConnectByeTimes = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.NoConnectByeTimes)?.SettingValue[0]);
-        int effectiveTimes = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.EffectiveTimes)?.SettingValue[0]);
-        int connectByeTimes = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.ConnectByeTimes)?.SettingValue[0]);
-        int ringTims = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.RingTims)?.SettingValue[0]);
-        var list = await _trCallRecordRepositoryEx.GetCallHotLineList(dto.StartTime, dto.EndTime, dto.gateway, noConnectByeTimes, effectiveTimes, connectByeTimes, ringTims);
-        return list;
-    }
+        => await _callReportApplication.GetCallHotLineListAsync(dto, HttpContext.RequestAborted);
 
     /// <summary>
     /// 热线号码统计导出
@@ -454,23 +433,10 @@ public class BiCallController : BaseController
     /// <returns></returns>
     [HttpPost("gateway-query/export")]
     public async Task<FileStreamResult> ExportQueryGatetWay(ExportExcelDto<BiQueryGateWayDto> dto)
-    {
-        //获取配置
-        int noConnectByeTimes = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.NoConnectByeTimes)?.SettingValue[0]);
-        int effectiveTimes = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.EffectiveTimes)?.SettingValue[0]);
-        int connectByeTimes = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.ConnectByeTimes)?.SettingValue[0]);
-        int ringTims = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.RingTims)?.SettingValue[0]);
-        var list = await _trCallRecordRepositoryEx.GetCallHotLineList(dto.QueryDto.StartTime, dto.QueryDto.EndTime, dto.QueryDto.gateway, noConnectByeTimes, effectiveTimes, connectByeTimes, ringTims);
-
-        dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
-
-        var dtos = list
-            .Select(stu => _mapper.Map(stu, typeof(CallHotLineDto), dynamicClass))
-            .Cast<object>()
-            .ToList();
-
-        var stream = ExcelHelper.CreateStream(dtos);
-
-        return ExcelStreamResult(stream, "热线号码统计");
-    }
+        => ExcelStreamResult(
+            await _exportApplication.FittingAsync(
+                dto,
+                await _callReportApplication.GetCallHotLineListAsync(dto.QueryDto, HttpContext.RequestAborted)
+                )
+            , "热线号码统计");
 }

+ 1 - 1
src/Hotline.Application.Tests/Application/YiBinCallReportApplicationTest.cs

@@ -38,7 +38,7 @@ public class YiBinCallReportApplicationTest
     [Fact]
     public async Task QuerySeatCall_Test()
     {
-        var inDto = new ReportPagedRequest
+        var inDto = new ReportRequiredPagedRequest
         {
             StartTime = "2024-06-01".ObjToDate(),
             EndTime = "2024-06-30 23:59:59".ObjToDate()

+ 1 - 1
src/Hotline.Application.Tests/Application/ZiGongCallReportApplicationTest.cs

@@ -33,7 +33,7 @@ public class ZiGongCallReportApplicationTest
     [Fact]
     public async Task QuerySeatCall_Test()
     {
-        var inDto = new ReportPagedRequest
+        var inDto = new ReportRequiredPagedRequest
         {
             StartTime = "2024-06-01".ObjToDate(),
             EndTime = DateTime.Now

+ 28 - 0
src/Hotline.Application/ExportExcel/ExportApplication.cs

@@ -1,4 +1,8 @@
 
+using Hotline.Share.Dtos.CallCenter;
+using Hotline.Share.Dtos.Order;
+using Hotline.Tools;
+using MapsterMapper;
 using Microsoft.AspNetCore.Mvc;
 using MiniExcelLibs;
 using XF.Domain.Dependency;
@@ -7,6 +11,13 @@ namespace Hotline.Application.ExportExcel
 {
     public class ExportApplication : IExportApplication, IScopeDependency
     {
+        private readonly IMapper _mapper;
+
+        public ExportApplication(IMapper mapper)
+        {
+            _mapper = mapper;
+        }
+
         /// <summary>
         /// 导出数据
         /// </summary>
@@ -24,5 +35,22 @@ namespace Hotline.Application.ExportExcel
                 FileDownloadName = !string.IsNullOrEmpty(name) ? DateTime.Now.ToString("yyyyMMddhhmmss") + ".xlsx" : name
             };
         }
+
+        public async Task<Stream> FittingAsync<T, D>(ExportExcelDto<D> dto, List<T> items, Action<List<T>>? action = null)
+        {
+            if (items != null && items.Count > 0)
+            {
+                action?.Invoke(items);
+            }
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = items
+                .Select(stu => _mapper.Map(stu, typeof(BiCallDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            return ExcelHelper.CreateStream(dtos);
+        }
     }
 }

+ 4 - 1
src/Hotline.Application/ExportExcel/IExportApplication.cs

@@ -1,4 +1,5 @@
-using Microsoft.AspNetCore.Mvc;
+using Hotline.Share.Dtos.Order;
+using Microsoft.AspNetCore.Mvc;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -17,5 +18,7 @@ namespace Hotline.Application.ExportExcel
         /// <param name="name">导出文件名(不传则生成yyyyMMddhhmmss)</param>
         /// <returns></returns>
         FileStreamResult ExportData<T>(List<T> list, string? name);
+
+        Task<Stream> FittingAsync<T, D>(ExportExcelDto<D> dto, List<T> items, Action<List<T>>? action = null);
     }
 }

+ 23 - 10
src/Hotline.Application/StatisticalReport/CallReport/CallReportApplicationBase.cs

@@ -34,6 +34,15 @@ public abstract class CallReportApplicationBase : ICallReportApplication
         _telRestRepository = telRestRepository;
     }
 
+    public virtual async Task<List<CallHotLineDto>> GetCallHotLineListAsync(BiQueryGateWayDto dto, CancellationToken requestAborted)
+    {
+        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
+        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
+        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
+        int ringTimes = _systemSettingCacheManager.RingTimes;
+        return await _callNativeRepository.GetCallHotLineListAsync(dto, noConnectByeTimes, effectiveTimes, connectByeTimes, ringTimes);
+    }
+
     public virtual async Task<List<TrCallHourDto>> GetCallHourListAsync(BiQueryHourCallDto dto, CancellationToken requestAborted)
     {
         int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
@@ -42,9 +51,17 @@ public abstract class CallReportApplicationBase : ICallReportApplication
         return await _callNativeRepository.GetCallHourList(dto.StartTime, dto.EndTime, noConnectByeTimes, effectiveTimes, connectByeTimes, dto.Source);
     }
 
+    public async Task<TotalData<BiSeatSwitchDto>> GetCallListAsync(QueryCallListDto dto, CancellationToken requestAborted)
+    {
+        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
+        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
+        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
+        return await _callNativeRepository.GetCallList(dto, noConnectByeTimes, effectiveTimes, connectByeTimes);
+    }
+
     public virtual async Task<List<BiCallDto>> QueryCallsAsync(BiQueryCallsDto dto, CancellationToken cancellationToken)
     {
-        return await _callNativeRepository.GetQueryCalls(dto.StartTime, dto.EndTime, dto.Line);
+        return await _callNativeRepository.GetQueryCalls(dto.StartTime.Value, dto.EndTime.Value, dto.Line);
     }
 
     /// <summary>
@@ -132,7 +149,7 @@ public abstract class CallReportApplicationBase : ICallReportApplication
         int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
         //接通秒挂时间
         int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
-        return await _callNativeRepository.QueryCallsHourDetail(dto.StartTime, dto.EndTime, noConnectByeTimes, effectiveTimes, connectByeTimes, CallInOverConnRingTime, SeatChaoTime, dto.Line);
+        return await _callNativeRepository.QueryCallsHourDetail(dto.StartTime.Value, dto.EndTime.Value, noConnectByeTimes, effectiveTimes, connectByeTimes, CallInOverConnRingTime, SeatChaoTime, dto.Line);
     }
 
     /// <summary>
@@ -140,7 +157,7 @@ public abstract class CallReportApplicationBase : ICallReportApplication
     /// </summary>
     /// <param name="dto"></param>
     /// <returns></returns>
-    public virtual async Task<IList<BiSeatCallsDto>> QuerySeatCallAsync(ReportPagedRequest dto, CancellationToken cancellationToken)
+    public virtual async Task<List<BiSeatCallsDto>> QuerySeatCallAsync(ReportRequiredPagedRequest dto, CancellationToken cancellationToken)
     {
         int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
         int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
@@ -149,8 +166,8 @@ public abstract class CallReportApplicationBase : ICallReportApplication
         var list = await _userRepository.Queryable()
               .LeftJoin<CallNative>((u, c) => u.Id == c.UserId)
               .Where(u => !u.IsDeleted && u.UserType == EUserType.Seat)
-              .WhereIF(dto.StartTime.HasValue, (u, c) => c.CreationTime >= dto.StartTime.Value)
-              .WhereIF(dto.EndTime.HasValue, (u, c) => c.CreationTime <= dto.EndTime.Value)
+              .Where((u, c) => c.CreationTime >= dto.StartTime)
+              .Where((u, c) => c.CreationTime <= dto.EndTime)
               .GroupBy((u, c) => new { c.UserName, c.UserId })
               .Select((u, c) => new BiSeatCallsDto
               {
@@ -185,15 +202,11 @@ public abstract class CallReportApplicationBase : ICallReportApplication
 
     }
 
-    public Task<List<BiSeatCallsDto>> QuerySeatCallAsync(ReportRequiredPagedRequest dto, CancellationToken cancellationToken)
-    {
-        throw new NotImplementedException();
-    }
 
     public virtual async Task<(int, List<BiSeatSwitchDto>)> QuerySeatSwitchAsync(QuerySeatSwitchRequest dto, CancellationToken cancellationToken)
     {
         return await _callNativeRepository.Queryable()
-            .Where(x => !string.IsNullOrEmpty(x.TelNo))
+            .Where(x => !string.IsNullOrEmpty(x.AgentTransferNumber))
             .WhereIF(!string.IsNullOrEmpty(dto.UserName), x => x.UserName.Contains(dto.UserName))
             .WhereIF(!string.IsNullOrEmpty(dto.CDPN), x => x.ToNo.Contains(dto.CDPN))
             .Where(x => x.CreationTime >= dto.StartTime)

+ 12 - 3
src/Hotline.Application/StatisticalReport/CallReport/YiBinCallReportApplication.cs

@@ -50,7 +50,7 @@ public class YiBinCallReportApplication : CallReportApplicationBase, ICallReport
 
     public override async Task<List<BiCallDto>> QueryCallsAsync(BiQueryCallsDto dto, CancellationToken cancellationToken)
     {
-        return await _trCallRecordRepositoryEx.GetQueryCalls(dto.StartTime, dto.EndTime, dto.Keyword);
+        return await _trCallRecordRepositoryEx.GetQueryCalls(dto.StartTime.Value, dto.EndTime.Value, dto.Keyword);
     }
 
     /// <summary>
@@ -133,7 +133,7 @@ public class YiBinCallReportApplication : CallReportApplicationBase, ICallReport
     /// </summary>
     /// <param name="dto"></param>
     /// <returns></returns>
-    public override async Task<IList<BiSeatCallsDto>> QuerySeatCallAsync(ReportRequiredPagedRequest dto, CancellationToken cancellationToken)
+    public override async Task<List<BiSeatCallsDto>> QuerySeatCallAsync(ReportRequiredPagedRequest dto, CancellationToken cancellationToken)
     {
         //获取配置
         int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
@@ -192,7 +192,7 @@ public class YiBinCallReportApplication : CallReportApplicationBase, ICallReport
         int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
         //接通秒挂时间
         int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
-        return await _trCallRecordRepositoryEx.QueryCallsHourDetail(dto.StartTime, dto.EndTime, noConnectByeTimes, effectiveTimes
+        return await _trCallRecordRepositoryEx.QueryCallsHourDetail(dto.StartTime.Value, dto.EndTime.Value, noConnectByeTimes, effectiveTimes
               , connectByeTimes, CallInOverConnRingTime, SeatChaoTime, dto.Keyword);
     }
 
@@ -224,4 +224,13 @@ public class YiBinCallReportApplication : CallReportApplicationBase, ICallReport
         int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
         return await _trCallRecordRepositoryEx.GetCallHourList(dto.StartTime, dto.EndTime, noConnectByeTimes, effectiveTimes, connectByeTimes, dto.Source);
     }
+
+    public override async Task<List<CallHotLineDto>> GetCallHotLineListAsync(BiQueryGateWayDto dto, CancellationToken requestAborted)
+    {
+        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
+        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
+        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
+        var ringTims = _systemSettingCacheManager.RingTimes;
+        return await _trCallRecordRepositoryEx.GetCallHotLineList(dto.StartTime, dto.EndTime, dto.Gateway, noConnectByeTimes, effectiveTimes, connectByeTimes, ringTims); ;
+    }
 }

+ 0 - 38
src/Hotline.Application/StatisticalReport/ExportApplication.cs

@@ -1,38 +0,0 @@
-using Hotline.Share.Dtos.CallCenter;
-using Hotline.Share.Dtos.Order;
-using Hotline.Tools;
-using MapsterMapper;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using XF.Domain.Dependency;
-
-namespace Hotline.Application.StatisticalReport;
-public class ExportApplication : IExportApplication, IScopeDependency
-{
-    private readonly IMapper _mapper;
-
-    public ExportApplication(IMapper mapper)
-    {
-        _mapper = mapper;
-    }
-
-    public async Task<Stream> FittingAsync<T, D>( ExportExcelDto<D> dto, List<T> items,Action<List<T>>? action = null)
-    {
-        if (items != null && items.Count > 0)
-        {
-            action?.Invoke(items);
-        }
-
-        dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
-
-        var dtos = items
-            .Select(stu => _mapper.Map(stu, typeof(BiCallDto), dynamicClass))
-            .Cast<object>()
-            .ToList();
-
-        return ExcelHelper.CreateStream(dtos);
-    }
-}

+ 2 - 0
src/Hotline.Application/StatisticalReport/ICallReportApplication.cs

@@ -34,5 +34,7 @@ namespace Hotline.Application.StatisticalReport
         Task<List<QueryCallsDetailDto>> QueryCallsHourDetailAsync(BiQueryCallsDto dto, CancellationToken cancellationToken);
         Task<(int, List<BiSeatSwitchDto>)> QuerySeatSwitchAsync(QuerySeatSwitchRequest dto, CancellationToken requestAborted);
         Task<List<TrCallHourDto>> GetCallHourListAsync(BiQueryHourCallDto dto, CancellationToken requestAborted);
+        Task<TotalData<BiSeatSwitchDto>> GetCallListAsync(QueryCallListDto dto, CancellationToken requestAborted);
+        Task<List<CallHotLineDto>> GetCallHotLineListAsync(BiQueryGateWayDto dto, CancellationToken requestAborted);
     }
 }

+ 0 - 14
src/Hotline.Application/StatisticalReport/IExportApplication.cs

@@ -1,14 +0,0 @@
-
-using Hotline.Share.Dtos.CallCenter;
-using Hotline.Share.Dtos.Order;
-
-namespace Hotline.Application.StatisticalReport;
-
-/// <summary>
-/// 导出服务
-/// </summary>
-public interface IExportApplication
-{
-    Task<Stream> FittingAsync<T, D>( ExportExcelDto<D>dto, List<T> items, Action<List<T>>? action = null);
-}
-

+ 12 - 0
src/Hotline.Application/Systems/BaseDataApplication.cs

@@ -99,4 +99,16 @@ public class BaseDataApplication : IScopeDependency
         Add(SysDicTypeConsts.DissatisfiedReason);
         return this;
     }
+
+    public BaseDataApplication CallForwardingSource()
+    {
+        Add(SysDicTypeConsts.CallForwardingSource);
+        return this;
+    }
+
+    public BaseDataApplication CallForwardingType()
+    {
+        Add(SysDicTypeConsts.CallForwardingType);
+        return this;
+    }
 }

+ 60 - 0
src/Hotline.Repository.SqlSugar/CallCenter/CallNativeRepository.cs

@@ -178,4 +178,64 @@ public class CallNativeRepository : BaseRepository<CallNative>, ICallNativeRepos
 
         return listCall;
     }
+
+    /// <summary>
+    /// 通话时段统计明细
+    /// </summary>
+    /// <returns></returns>
+    public async Task<TotalData<BiSeatSwitchDto>> GetCallList(QueryCallListDto dto, int noConnectByeTimes, int effectiveTimes, int connectByeTimes)
+    {
+        TimeSpan endHourTo = DateTime.Now.TimeOfDay;
+        if (dto.StartHourTo.HasValue)
+        {
+            endHourTo = dto.StartHourTo.Value.Add(new TimeSpan(1, 0, 0));
+        }
+        RefAsync<int> total = 0;
+        var res = await Db.Queryable<CallNative>()
+            .Where(x => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime)
+            .Where(x => x.Direction == ECallDirection.In)
+            .WhereIF(!string.IsNullOrEmpty(dto.Source), x => x.ToNo == dto.Source)
+            .WhereIF(!string.IsNullOrEmpty(dto.Type) && ("QueueBye".Equals(dto.Type) || "queueByeCount".Equals(dto.Type)), x => x.WaitDuration > 0 && x.RingDuration == 0) //队列挂断
+            .WhereIF(!string.IsNullOrEmpty(dto.Type) && ("IvrBye".Equals(dto.Type) || "ivrByeCount".Equals(dto.Type)), x => x.BeginIvrTime.HasValue && !x.BeginQueueTime.HasValue && !x.BeginRingTime.HasValue && x.AnsweredTime == null)//IVR挂断
+            .WhereIF(!string.IsNullOrEmpty(dto.Type) && ("Effective".Equals(dto.Type) || "effectiveCount".Equals(dto.Type)), x => x.Duration >= effectiveTimes) //有效接通
+            .WhereIF(!string.IsNullOrEmpty(dto.Type) && "Invalid".Equals(dto.Type), x => x.Duration > 0 && x.Duration < effectiveTimes)//无效接通
+            .WhereIF(!string.IsNullOrEmpty(dto.Type) && "connectByeCount".Equals(dto.Type), x => x.Duration > 0 && x.Duration <= connectByeTimes)  //接通秒挂
+            .WhereIF(!string.IsNullOrEmpty(dto.Type) && "noConnectByeCount".Equals(dto.Type), x => x.Duration == 0 && x.RingDuration <= noConnectByeTimes && x.RingDuration > 0)  //未接通秒挂
+            .WhereIF(!string.IsNullOrEmpty(dto.Type) && "count".Equals(dto.Type), x =>
+            (x.Duration == 0 && x.RingDuration <= noConnectByeTimes && x.RingDuration > 0)  //未接通秒挂
+            || (x.Duration > 0 && x.Duration <= connectByeTimes)  //接通秒挂
+            || (x.Duration >= effectiveTimes)//有效接通
+            || (x.BeginIvrTime.HasValue && !x.BeginQueueTime.HasValue && !x.BeginRingTime.HasValue && x.AnsweredTime == null) //IVR挂断
+            || (x.WaitDuration > 0 && x.RingDuration == 0))//队列挂断
+            .WhereIF(dto.StartHourTo.HasValue, x => SqlFunc.ToTime(x.CreationTime.ToString("HH:mm:ss")) >= dto.StartHourTo.Value && SqlFunc.ToTime(x.CreationTime.ToString("HH:mm:ss")) < endHourTo)
+            .Select(x => new BiSeatSwitchDto
+            {
+                CPN = x.FromNo,
+                CDPN = x.ToNo,
+                CreatedTime = x.CreationTime
+            })
+            .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
+        return new TotalData<BiSeatSwitchDto>(res, total.Value);
+    }
+
+    public async Task<List<CallHotLineDto>> GetCallHotLineListAsync(BiQueryGateWayDto dto, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, int ringTims)
+    {
+        var list = await Db.Queryable<CallNative>()
+            .Where(x => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime && SqlFunc.Length(x.TelNo) > 4)
+            .WhereIF(!string.IsNullOrEmpty(dto.Gateway), x => x.TelNo == dto.Gateway)
+            .GroupBy(x => x.TelNo)
+            .Select(x => new CallHotLineDto()
+            {
+                GateWay = x.TelNo,
+                CallInCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.Direction == ECallDirection.In, 1, 0)),//接通
+                ConnectCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.Direction == ECallDirection.In && x.AnsweredTime != null, 1, 0)),//接通
+                NoConnectByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.Direction == ECallDirection.In && x.Duration == 0 && x.RingDuration <= noConnectByeTimes && x.RingDuration > 0, 1, 0)), //未接通秒挂
+                EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.Direction == ECallDirection.In && x.Duration >= effectiveTimes, 1, 0)),//有效接通
+                DurationSum = SqlFunc.AggregateSum(SqlFunc.IIF(x.Direction == ECallDirection.In && x.AnsweredTime != null, x.Duration, 0)),//通话总时长
+                ConnectByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.Direction == ECallDirection.In && x.Duration > 0 && x.Duration <= connectByeTimes, 1, 0)), //接通秒挂
+                TimelyAnswerCount = SqlFunc.AggregateSum(SqlFunc.IIF(x.Direction == ECallDirection.In && x.AnsweredTime != null && x.RingDuration <= ringTims, 1, 0))//及时应答
+            }).ToListAsync();
+
+        return list;
+    }
 }

+ 16 - 16
src/Hotline.Repository.SqlSugar/CallCenter/TrCallRecordRepository.cs

@@ -178,39 +178,39 @@ namespace Hotline.Repository.SqlSugar.CallCenter
         /// 通话时段统计明细
         /// </summary>
         /// <returns></returns>
-        public async Task<TotalDataList<>> GetCallList(DateTime beginDate, DateTime? endDate, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, string type, string source, TimeSpan? startHourTo, int pageIndex, int pageSize)
+        public async Task<TotalData<BiSeatSwitchDto>> GetCallList(QueryCallListDto dto, int noConnectByeTimes, int effectiveTimes, int connectByeTimes)
         {
             TimeSpan endHourTo = DateTime.Now.TimeOfDay;
-            if (startHourTo.HasValue)
+            if (dto.StartHourTo.HasValue)
             {
-                endHourTo = startHourTo.Value.Add(new TimeSpan(1, 0, 0));
+                endHourTo = dto.StartHourTo.Value.Add(new TimeSpan(1, 0, 0));
             }
             RefAsync<int> total = 0;
             var res = await Db.Queryable<TrCallRecord>()
-                .Where(x => x.CreatedTime >= beginDate && x.CreatedTime <= endDate)
+                .Where(x => x.CreatedTime >= dto.StartTime && x.CreatedTime <= dto.EndTime)
                 .Where(x => x.CallDirection == ECallDirection.In)
-                .WhereIF(!string.IsNullOrEmpty(source), x => x.CDPN == source)
-                .WhereIF(!string.IsNullOrEmpty(type) && ("QueueBye".Equals(type) || "queueByeCount".Equals(type)), x => x.QueueTims > 0 && x.RingTimes == 0) //队列挂断
-                .WhereIF(!string.IsNullOrEmpty(type) && ("IvrBye".Equals(type) || "ivrByeCount".Equals(type)), x => x.BeginIvrTime.HasValue && !x.BeginQueueTime.HasValue && !x.BeginRingTime.HasValue && x.OnState == EOnState.NoOn)//IVR挂断
-                .WhereIF(!string.IsNullOrEmpty(type) && ("Effective".Equals(type) || "effectiveCount".Equals(type)), x => x.Duration >= effectiveTimes) //有效接通
-                .WhereIF(!string.IsNullOrEmpty(type) && "Invalid".Equals(type), x => x.Duration > 0 && x.Duration < effectiveTimes)//无效接通
-                .WhereIF(!string.IsNullOrEmpty(type) && "connectByeCount".Equals(type), x => x.Duration > 0 && x.Duration <= connectByeTimes)  //接通秒挂
-                .WhereIF(!string.IsNullOrEmpty(type) && "noConnectByeCount".Equals(type), x => x.Duration == 0 && x.RingTimes <= noConnectByeTimes && x.RingTimes > 0)  //未接通秒挂
-                .WhereIF(!string.IsNullOrEmpty(type) && "count".Equals(type), x =>
+                .WhereIF(!string.IsNullOrEmpty(dto.Source), x => x.CDPN == dto.Source)
+                .WhereIF(!string.IsNullOrEmpty(dto.Type) && ("QueueBye".Equals(dto.Type) || "queueByeCount".Equals(dto.Type)), x => x.QueueTims > 0 && x.RingTimes == 0) //队列挂断
+                .WhereIF(!string.IsNullOrEmpty(dto.Type) && ("IvrBye".Equals(dto.Type) || "ivrByeCount".Equals(dto.Type)), x => x.BeginIvrTime.HasValue && !x.BeginQueueTime.HasValue && !x.BeginRingTime.HasValue && x.OnState == EOnState.NoOn)//IVR挂断
+                .WhereIF(!string.IsNullOrEmpty(dto.Type) && ("Effective".Equals(dto.Type) || "effectiveCount".Equals(dto.Type)), x => x.Duration >= effectiveTimes) //有效接通
+                .WhereIF(!string.IsNullOrEmpty(dto.Type) && "Invalid".Equals(dto.Type), x => x.Duration > 0 && x.Duration < effectiveTimes)//无效接通
+                .WhereIF(!string.IsNullOrEmpty(dto.Type) && "connectByeCount".Equals(dto.Type), x => x.Duration > 0 && x.Duration <= connectByeTimes)  //接通秒挂
+                .WhereIF(!string.IsNullOrEmpty(dto.Type) && "noConnectByeCount".Equals(dto.Type), x => x.Duration == 0 && x.RingTimes <= noConnectByeTimes && x.RingTimes > 0)  //未接通秒挂
+                .WhereIF(!string.IsNullOrEmpty(dto.Type) && "count".Equals(dto.Type), x =>
                 (x.Duration == 0 && x.RingTimes <= noConnectByeTimes && x.RingTimes > 0)  //未接通秒挂
                 || (x.Duration > 0 && x.Duration <= connectByeTimes)  //接通秒挂
                 || (x.Duration >= effectiveTimes)//有效接通
                 || (x.BeginIvrTime.HasValue && !x.BeginQueueTime.HasValue && !x.BeginRingTime.HasValue && x.OnState == EOnState.NoOn) //IVR挂断
                 || (x.QueueTims > 0 && x.RingTimes == 0))//队列挂断
-                .WhereIF(startHourTo.HasValue, x => SqlFunc.ToTime(x.CreatedTime.ToString("HH:mm:ss")) >= startHourTo.Value && SqlFunc.ToTime(x.CreatedTime.ToString("HH:mm:ss")) < endHourTo)
-                .Select(x => new
+                .WhereIF(dto.StartHourTo.HasValue, x => SqlFunc.ToTime(x.CreatedTime.ToString("HH:mm:ss")) >= dto.StartHourTo.Value && SqlFunc.ToTime(x.CreatedTime.ToString("HH:mm:ss")) < endHourTo)
+                .Select(x => new BiSeatSwitchDto
                 {
                     CPN = x.CPN,
                     CDPN = x.CDPN,
                     CreatedTime = x.CreatedTime
                 })
-                .ToPageListAsync(pageIndex, pageSize, total);
-            return new { Data = res, Total = total.Value };
+                .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
+            return new TotalData<BiSeatSwitchDto>(res, total.Value);
         }
 
         public async Task<List<CallHotLineDto>> GetCallHotLineList(DateTime beginDate, DateTime endDate, string lineNum, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, int ringTims)

+ 42 - 9
src/Hotline.Share/Dtos/CallCenter/BiQueryCallsDto.cs

@@ -9,7 +9,7 @@ public record BiQueryCallsDto : ReportPagedRequest
     /// 开始时间
     /// </summary>
     [Required(ErrorMessage = "开始时间不能为空")]
-    public new DateTime StartTime
+    public override DateTime? StartTime
     {
         get { return base.StartTime ?? throw new InvalidOperationException("开始时间不能为空"); }
         set { base.StartTime = value; }
@@ -19,10 +19,16 @@ public record BiQueryCallsDto : ReportPagedRequest
     /// 结束时间
     /// </summary>
     [Required(ErrorMessage = "结束时间不能为空")]
-    public new DateTime EndTime
+    public override DateTime? EndTime
     {
-        get { return base.StartTime ?? throw new InvalidOperationException("结束时间不能为空"); }
-        set { base.StartTime = value; }
+        get {
+            if (base.EndTime == null)
+                throw new InvalidOperationException("结束时间不能为空");
+            if (base.EndTime.Value.Hour == 0 && base.EndTime.Value.Minute == 0 && base.EndTime.Value.Second == 0)
+                return base.EndTime.Value.AddDays(1).AddSeconds(-1);
+            return base.EndTime; 
+        }
+        set { base.EndTime = value; }
     }
 
     /// <summary>
@@ -36,6 +42,17 @@ public record BiQueryCallsDto : ReportPagedRequest
     public string? TypeCode { get; set; } = "1";
 }
 
+public record QueryCallListDto : PagedRequest
+{
+    [Required(ErrorMessage = "开始时间不能为空")]
+    public DateTime StartTime { get; set; }
+    [Required(ErrorMessage = "结束时间不能为空")]
+    public DateTime EndTime { get; set; }
+    public string Type { get; set; }
+    public string Source { get; set; }
+    public TimeSpan? StartHourTo { get; set; }
+}
+
 public class BiQueryHourCallDto
 {
 
@@ -52,16 +69,16 @@ public class BiQueryGateWayDto
 
     public DateTime EndTime { get; set; }
 
-    public string gateway { get; set; }
+    public string Gateway { get; set; }
 }
 
-public class TotalDataList<T>
+public class TotalList<T>
 {
-    public TotalDataList()
+    public TotalList()
     {
-        
+
     }
-    public TotalDataList(List<T> list, T total)
+    public TotalList(List<T> list, T total)
     {
         List = list;
         Total = total;
@@ -69,4 +86,20 @@ public class TotalDataList<T>
 
     public T Total { get; set; }
     public List<T> List { get; set; }
+}
+
+public class TotalData<T>
+{
+    public TotalData()
+    {
+
+    }
+    public TotalData(List<T> list, int total)
+    {
+        Data = list;
+        Total = total;
+    }
+
+    public int Total { get; set; }
+    public List<T> Data { get; set; }
 }

+ 0 - 8
src/Hotline.Share/Dtos/TrCallCenter/TrTelDao.cs

@@ -896,14 +896,6 @@ namespace Hotline.Share.Dtos.TrCallCenter
         public string Id { get; set; }
     }
 
-    public class TrDto
-    {
-        prop
-        CPN = x.CPN,
-                    CDPN = x.CDPN,
-                    CreatedTime = x.CreatedTime
-    }
-
     public class TrCallDtoNew
     {
         /// <summary>

+ 4 - 4
src/Hotline.Share/Requests/PagedKeywordRequest.cs

@@ -92,7 +92,7 @@ public record ReportRequiredPagedRequest : PagedKeywordRequest
     /// 开始时间
     /// </summary>
     [Required(ErrorMessage = "开始时间不能为空")]
-    public new DateTime StartTime
+    public override DateTime? StartTime
     {
         get { return base.StartTime ?? throw new InvalidOperationException("开始时间不能为空"); }
         set { base.StartTime = value; }
@@ -102,10 +102,10 @@ public record ReportRequiredPagedRequest : PagedKeywordRequest
     /// 结束时间
     /// </summary>
     [Required(ErrorMessage = "结束时间不能为空")]
-    public new DateTime EndTime
+    public override DateTime? EndTime
     {
-        get { return base.StartTime ?? throw new InvalidOperationException("结束时间不能为空"); }
-        set { base.StartTime = value; }
+        get { return base.EndTime ?? throw new InvalidOperationException("结束时间不能为空"); }
+        set { base.EndTime = value; }
     }
 
     /// <summary>

+ 1 - 0
src/Hotline/Caching/Interfaces/ISystemSettingCacheManager.cs

@@ -11,5 +11,6 @@ namespace Hotline.Caching.Interfaces
         int ConnectByeTimes { get; }
         int CallInOverConnRingTime { get; }
         int SeatChaoTime { get; }
+        int RingTimes { get; }
     }
 }

+ 2 - 0
src/Hotline/Caching/Services/SystemSettingCacheManager.cs

@@ -47,5 +47,7 @@ namespace Hotline.Caching.Services
         public int CallInOverConnRingTime => int.Parse(GetSetting(SettingConstants.CallInOverConnRingTime)?.SettingValue[0]);
 
         public int SeatChaoTime => int.Parse(GetSetting(SettingConstants.SeatChaoTime)?.SettingValue[0]);
+
+        public int RingTimes => int.Parse(GetSetting(SettingConstants.RingTimes)?.SettingValue[0]);
     }
 }

+ 5 - 0
src/Hotline/CallCenter/Calls/CallNative.cs

@@ -165,5 +165,10 @@ namespace Hotline.CallCenter.Calls
         //public string? OrderNo { get; set; }
 
         //public string? Title { get; set; }
+
+        /// <summary>
+        /// 转接分机号
+        /// </summary>
+        public string? AgentTransferNumber { get; set; }
     }
 }

+ 2 - 0
src/Hotline/CallCenter/Calls/ICallNativeRepository.cs

@@ -9,4 +9,6 @@ public interface ICallNativeRepository : IRepository<CallNative>
     Task<List<BiCallDto>> GetQueryCalls(DateTime beginDate, DateTime endDate, string? Line);
     Task<List<QueryCallsDetailDto>> QueryCallsHourDetail(DateTime beginDate, DateTime endDate, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, int CallInOverConnRingTime, int SeatChaoTime, string? Line);
     Task<List<TrCallHourDto>?> GetCallHourList(DateTime beginDate, DateTime? endDate, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, string source);
+    Task<TotalData<BiSeatSwitchDto>> GetCallList(QueryCallListDto dto, int noConnectByeTimes, int effectiveTimes,int connectByeTimes);
+    Task<List<CallHotLineDto>> GetCallHotLineListAsync(BiQueryGateWayDto dto, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, int ringTimes);
 }

+ 2 - 4
src/Hotline/CallCenter/Calls/ITrCallRecordRepository.cs

@@ -24,8 +24,6 @@ namespace Hotline.CallCenter.Calls
 
 
         Task<List<CallHotLineDto>> GetCallHotLineList(DateTime beginDate, DateTime endDate, string lineNum, int noConnectByeTimes, int effectiveTimes, int connectByeTimes,int ringTims);
-
-        Task<object> GetCallList(DateTime beginDate, DateTime? endDate, int noConnectByeTimes, int effectiveTimes, int connectByeTimes, string type, string source, TimeSpan? startHourTo, int pageIndex, int pageSize);
-
-	}
+        Task<TotalData<BiSeatSwitchDto>> GetCallList(QueryCallListDto dto, int noConnectByeTimes, int effectiveTimes,int connectByeTimes);
+    }
 }

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

@@ -149,7 +149,7 @@ namespace Hotline.Settings
         /// <summary>
         /// 及时应答时间
         /// </summary>
-        public const string RingTims = "RingTims";
+        public const string RingTimes = "RingTims";
         /// <summary>
         /// 大屏数据展示推送间隔时间
         /// </summary>