Sfoglia il codice sorgente

【坐席话务统计分析】需支持点击数据打开明细表

libin 1 giorno fa
parent
commit
68382f3c02

+ 42 - 0
src/Hotline.Api/Controllers/Bi/BiCallController.cs

@@ -404,6 +404,48 @@ public class BiCallController : BaseController
     public async Task<IReadOnlyList<BiSeatCallsDto>> QuerySeatCallsAsync([FromQuery] ReportRequiredPagedRequest dto)
         => await _callReportApplication.QuerySeatCallAsync(dto, HttpContext.RequestAborted);
 
+    /// <summary>
+    /// 坐席话务统计分析明细
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpGet("seats/list")]
+    public async Task<PagedDto<CallRecordOutDto>> QuerySeatCallsListAsync([FromQuery] BiQueryCallsListDto dto)
+    {
+        var (total, items) = await _callReportApplication.QuerySeatCallsListAsync(dto, false);
+        return new PagedDto<CallRecordOutDto>(total, items);
+    }
+
+    /// <summary>
+    /// 坐席话务统计分析明细导出
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpPost("seats/list/export")]
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QuerySeatCallsListExportAsync([FromBody] ExportExcelDto<BiQueryCallsListDto> dto)
+    {
+        var (total, data) = await _callReportApplication.QuerySeatCallsListAsync(dto.QueryDto, dto.IsExportAll);
+
+        dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<CallRecordOutDto>(dto.ColumnInfos);
+
+        var dtos = data
+            .Select(stu => _mapper.Map(stu, typeof(CallRecordOutDto), dynamicClass))
+            .Cast<object>()
+            .ToList();
+
+        var stream = ExcelHelper.CreateStream(dtos);
+
+
+        return ExcelStreamResult(
+            _exportApplication.GetExcelStream(
+            dto,
+            (await _callReportApplication.QuerySeatCallsListAsync(dto.QueryDto, dto.IsExportAll)).Item2
+            ),
+            "坐席话务统计分析明细");
+    }
+
+
     /// <summary>
     /// 小休统计
     /// </summary>

+ 56 - 0
src/Hotline.Application/StatisticalReport/CallReport/CallReportApplicationBase.cs

@@ -19,6 +19,7 @@ using Hotline.Share.Tools;
 using JiebaNet.Segmenter.Common;
 using XingTang.Sdk;
 using Mapster;
+using NPOI.SS.Formula.Functions;
 
 namespace Hotline.Application.StatisticalReport.CallReport;
 
@@ -149,6 +150,61 @@ public abstract class CallReportApplicationBase : ICallReportApplication
                      RecordingAbsolutePath = p.AudioFile
                  }, true);
 
+        if (isAll)
+        {
+            return (0, await query.ToListAsync());
+        }
+
+        return await query.ToPagedListAsync(dto.PageIndex, dto.PageSize);
+    }
+
+    /// <summary>
+    /// 话务日期明细-呼入总量/接通总量
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    public virtual async Task<(int, List<CallRecordOutDto>)> QuerySeatCallsListAsync(BiQueryCallsListDto dto, bool isAll)
+    {
+        //超时接通量
+        int CallInOverConnRingTime = _systemSettingCacheManager.CallInOverConnRingTime;
+        //坐席超时挂断时间
+        int SeatChaoTime = _systemSettingCacheManager.SeatChaoTime;
+        //未接秒挂时间
+        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
+        //呼入有效时间
+        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
+        //接通秒挂时间
+        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
+
+        var recordPrefix = _systemSettingCacheManager.RecordPrefix;
+        var query = _callNativeRepository.Queryable(includeDeleted: true)
+                .LeftJoin<Order>((p, o) => p.Id == o.CallId)
+                .Where((p, o) => p.BeginIvrTime >= dto.StartTime && p.BeginIvrTime <= dto.EndTime && p.CallState != ECallState.Invalid)
+                .WhereIF(!string.IsNullOrEmpty(dto.UserId), (p, o) => p.UserId == dto.UserId)
+                .WhereIF(!string.IsNullOrEmpty(dto.UserName), (p, o) => p.UserName == dto.UserName)
+                .WhereIF(dto.FieldName == "inTotal", (p, o) => p.Direction == ECallDirection.In)                                                                                   //呼入总量
+                .WhereIF(dto.FieldName == "inAnswered", (p, o) => p.Direction == ECallDirection.In && p.AnsweredTime != null)                                                      //接通总量
+                .WhereIF(dto.FieldName == "inHangupImmediate", (p, o) => p.Direction == ECallDirection.In && p.AnsweredTime == null && p.RingDuration < noConnectByeTimes)         //呼入秒挂
+                .WhereIF(dto.FieldName == "inHanguped", (p, o) => p.Direction == ECallDirection.In && p.AnsweredTime == null && p.RingDuration >= noConnectByeTimes)               //呼入超时未接
+                .WhereIF(dto.FieldName == "inAvailableAnswer", (p, o) => p.Direction == ECallDirection.In && p.AnsweredTime != null && p.Duration >= effectiveTimes)               //有效接通量
+                .WhereIF(dto.FieldName == "inHangupImmediateWhenAnswered", (p, o) => p.Direction == ECallDirection.In && p.AnsweredTime != null && p.Duration < connectByeTimes)   //接通秒挂
+                .WhereIF(dto.FieldName == "outTotal", (p, o) => p.Direction == ECallDirection.Out)                                                                                 //呼出总量
+                .WhereIF(dto.FieldName == "outAnswered", (p, o) => p.Direction == ECallDirection.Out && p.AnsweredTime != null)                                                    //呼出接通量
+                .OrderByDescending((p, o) => p.BeginIvrTime)
+                .Select((p, o) => new CallRecordOutDto
+                {
+                    OtherAccept = p.Id,
+                    OrderId = o.Id,
+                    OrderNo = o.No,
+                    OrderTitle = o.Title,
+                    Cdpn = p.ToNo,
+                    Cpn = p.FromNo,
+                    RecordingFileUrl = recordPrefix + p.AudioFile,
+                    RecordingFileName = p.AudioFile,
+                    RecordingBaseAddress = recordPrefix,
+                    RecordingAbsolutePath = p.AudioFile
+                }, true);
+
         if (isAll)
         {
             return (0, await query.ToListAsync());

+ 48 - 0
src/Hotline.Application/StatisticalReport/CallReport/YiBinCallReportApplication.cs

@@ -19,6 +19,7 @@ using Microsoft.AspNetCore.Http;
 using Hotline.Share.Dtos;
 using MapsterMapper;
 using System.Threading;
+using NPOI.SS.Formula.Functions;
 
 namespace Hotline.Application.StatisticalReport.CallReport;
 
@@ -135,6 +136,53 @@ public class YiBinCallReportApplication : CallReportApplicationBase, ICallReport
         return await query.ToPagedListAsync(dto.PageIndex, dto.PageSize);
     }
 
+    /// <summary>
+    /// 话务日期明细-呼入总量/接通总量
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    public virtual async Task<(int, List<CallRecordOutDto>)> QuerySeatCallsListAsync(BiQueryCallsListDto dto, bool isAll)
+    {
+        //获取配置
+        int noConnectByeTimes = _systemSettingCacheManager.NoConnectByeTimes;
+        int effectiveTimes = _systemSettingCacheManager.EffectiveTimes;
+        int connectByeTimes = _systemSettingCacheManager.ConnectByeTimes;
+        int ringTims = _systemSettingCacheManager.RingTimes;
+        var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi).SettingValue;
+
+        var recordPrefix = _systemSettingCacheManager.RecordPrefix;
+        var query = _trCallRecordRepository.Queryable()
+                 .Includes(p => p.Order)
+                 .Where(p => p.CreatedTime >= dto.StartTime && p.CreatedTime <= dto.EndTime)
+                 .WhereIF(!string.IsNullOrEmpty(dto.UserId), p => p.UserId == dto.UserId)
+                 .WhereIF(!string.IsNullOrEmpty(dto.UserName), p => p.UserName == dto.UserName)
+                 .WhereIF(dto.FieldName == "inTotal", p => p.CallDirection == ECallDirection.In)                                                                                   //呼入总量
+                 .WhereIF(dto.FieldName == "inAnswered", p => p.CallDirection == ECallDirection.In && p.AnsweredTime != null)                                                      //接通总量
+                 .WhereIF(dto.FieldName == "inHangupImmediate", p => p.CallDirection == ECallDirection.In && p.AnsweredTime == null && p.RingTimes < noConnectByeTimes)            //呼入秒挂
+                 .WhereIF(dto.FieldName == "inHanguped", p => p.CallDirection == ECallDirection.In && p.AnsweredTime == null && p.RingTimes > ringTims)                            //呼入超时未接
+                 .WhereIF(dto.FieldName == "inAvailableAnswer", p => p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.Duration >= effectiveTimes)               //有效接通量
+                 .WhereIF(dto.FieldName == "inHangupImmediateWhenAnswered", p => p.CallDirection == ECallDirection.In && p.AnsweredTime != null && p.Duration < connectByeTimes)   //接通秒挂
+                 .WhereIF(dto.FieldName == "outTotal", p => p.CallDirection == ECallDirection.Out)                                                                                 //呼出总量
+                 .WhereIF(dto.FieldName == "outAnswered", p => p.CallDirection == ECallDirection.Out && p.AnsweredTime != null)                                                    //呼出接通量
+                 .OrderByDescending(p => p.BeginIvrTime)
+                 .Select(m => new CallRecordOutDto()
+                 {
+                     FromNo = m.CPN,
+                     ToNo = m.CDPN,
+                     Direction = m.CallDirection,
+                     EndTime = m.OverTime,
+                     OrderId = m.Order.Id,
+                     OrderTitle = m.Order.Title,
+                     OrderNo = m.Order.No
+                 }, true);
+
+        if (isAll)
+        {
+            return (0, await query.ToListAsync());
+        }
+        return await query.ToPagedListAsync(dto.PageIndex, dto.PageSize);
+    }
+
     /// <summary>
     /// 坐席话务统计分析
     /// </summary>

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

@@ -26,6 +26,13 @@ namespace Hotline.Application.StatisticalReport
         /// <returns></returns>
         Task<(int, List<CallRecordOutDto>)> QueryCallsDetailInTotalAsync(BiQueryCallsDto dto, bool isAll);
 
+        /// <summary>
+        /// 坐席话务统计分析明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        Task<(int, List<CallRecordOutDto>)> QuerySeatCallsListAsync(BiQueryCallsListDto dto, bool isAll);
+
         /// <summary>
         /// 坐席话务统计分析
         /// </summary>

+ 18 - 0
src/Hotline.Share/Dtos/CallCenter/BiQueryCallsDto.cs

@@ -19,6 +19,24 @@ public record BiQueryCallsDto : ReportRequiredPagedRequest
     public string? TypeCode { get; set; } = "1";
 }
 
+public record BiQueryCallsListDto : ReportRequiredPagedRequest
+{
+    /// <summary>
+    /// 用户Id
+    /// </summary>
+    public string? UserId { get; set; }
+
+    /// <summary>
+    /// 用户名称
+    /// </summary>
+    public string? UserName { get; set; }
+
+    /// <summary>
+    /// 字段类型
+    /// </summary>
+    public string? FieldName { get; set; }
+}
+
 public record QueryCallListDto : PagedRequest
 {
     public DateTime StartTime { get; set; }