Kaynağa Gözat

企业专席信件统计

tangjiang 8 ay önce
ebeveyn
işleme
a1e41ef47a

+ 190 - 88
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -13,19 +13,14 @@ using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.Bi;
 using Hotline.Share.Dtos.Bigscreen;
 using Hotline.Share.Dtos.CallCenter;
-using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Requests;
 using Hotline.Tools;
-using JiebaNet.Segmenter.Common;
 using MapsterMapper;
 using Microsoft.AspNetCore.Mvc;
-using Microsoft.IdentityModel.Tokens;
-using MongoDB.Bson;
-using Nacos.V2.Utils;
 using SqlSugar;
 using System.Data;
 using XF.Domain.Authentications;
@@ -3443,89 +3438,89 @@ namespace Hotline.Api.Controllers.Bi
             return ExcelStreamResult(stream, "热点受理类型明细");
         }
 
-		/// <summary>
-		/// 甄别申请统计
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpGet("screen-apply")]
-		public async Task<PagedDto<OrderScreenApplyVo>> OrderScreenApply([FromQuery] OrderScreenApplyPagedRequest dto)
-		{
-			var (total, items) = await _orderApplication.OrderScreenApply(dto).ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
-			return new PagedDto<OrderScreenApplyVo>(total, items);
-		}
-		
-        /// <summary>
-		/// 甄别申请统计导出
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpPost("screen-apply-export")]
-		public async Task<FileStreamResult> OrderScreenApplyExport([FromBody] ExportExcelDto<OrderScreenApplyPagedRequest> dto)
-		{
-			var query = _orderApplication.OrderScreenApply(dto.QueryDto);
-
-			List<OrderScreenApplyVo> datas;
-			if (dto.IsExportAll)
-			{
-				datas = await query.ToListAsync(HttpContext.RequestAborted);
-			}
-			else
-			{
-				var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
-				datas = items;
-			}
-			dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
-			var dtos = datas
-				.Select(stu => _mapper.Map(stu, typeof(OrderScreenApplyVo), dynamicClass))
-				.Cast<object>()
-				.ToList();
-
-			var stream = ExcelHelper.CreateStream(dtos);
-			return ExcelStreamResult(stream, "甄别申请统计");
-		}
-
-		/// <summary>
-		/// 甄别审批统计
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpGet("screen-audit")]
-		public async Task<PagedDto<OrderScreenAuditVo>> OrderScreenAudit([FromQuery] OrderScreenAuditPagedRequest dto)
-		{
-			var (total, items) = await _orderApplication.OrderScreenAudit(dto).ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
-			return new PagedDto<OrderScreenAuditVo>(total, items);
-		}
-		
-        /// <summary>
-		/// 甄别审批统计导出
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpPost("screen-audit-export")]
-		public async Task<FileStreamResult> OrderScreenAuditExport([FromBody] ExportExcelDto<OrderScreenAuditPagedRequest> dto)
-		{
-			var query = _orderApplication.OrderScreenAudit(dto.QueryDto);
-
-			List<OrderScreenAuditVo> datas;
-			if (dto.IsExportAll)
-			{
-				datas = await query.ToListAsync(HttpContext.RequestAborted);
-			}
-			else
-			{
-				var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
-				datas = items;
-			}
-			dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
-			var dtos = datas
-				.Select(stu => _mapper.Map(stu, typeof(OrderScreenAuditVo), dynamicClass))
-				.Cast<object>()
-				.ToList();
-
-			var stream = ExcelHelper.CreateStream(dtos);
-			return ExcelStreamResult(stream, "甄别审批统计");
-		}
+        /// <summary>
+        /// 甄别申请统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("screen-apply")]
+        public async Task<PagedDto<OrderScreenApplyVo>> OrderScreenApply([FromQuery] OrderScreenApplyPagedRequest dto)
+        {
+            var (total, items) = await _orderApplication.OrderScreenApply(dto).ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
+            return new PagedDto<OrderScreenApplyVo>(total, items);
+        }
+
+        /// <summary>
+        /// 甄别申请统计导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("screen-apply-export")]
+        public async Task<FileStreamResult> OrderScreenApplyExport([FromBody] ExportExcelDto<OrderScreenApplyPagedRequest> dto)
+        {
+            var query = _orderApplication.OrderScreenApply(dto.QueryDto);
+
+            List<OrderScreenApplyVo> datas;
+            if (dto.IsExportAll)
+            {
+                datas = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+                datas = items;
+            }
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+            var dtos = datas
+                .Select(stu => _mapper.Map(stu, typeof(OrderScreenApplyVo), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+            return ExcelStreamResult(stream, "甄别申请统计");
+        }
+
+        /// <summary>
+        /// 甄别审批统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("screen-audit")]
+        public async Task<PagedDto<OrderScreenAuditVo>> OrderScreenAudit([FromQuery] OrderScreenAuditPagedRequest dto)
+        {
+            var (total, items) = await _orderApplication.OrderScreenAudit(dto).ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
+            return new PagedDto<OrderScreenAuditVo>(total, items);
+        }
+
+        /// <summary>
+        /// 甄别审批统计导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("screen-audit-export")]
+        public async Task<FileStreamResult> OrderScreenAuditExport([FromBody] ExportExcelDto<OrderScreenAuditPagedRequest> dto)
+        {
+            var query = _orderApplication.OrderScreenAudit(dto.QueryDto);
+
+            List<OrderScreenAuditVo> datas;
+            if (dto.IsExportAll)
+            {
+                datas = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+                datas = items;
+            }
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+            var dtos = datas
+                .Select(stu => _mapper.Map(stu, typeof(OrderScreenAuditVo), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+            return ExcelStreamResult(stream, "甄别审批统计");
+        }
 
         /// <summary>
         /// 未签收统计
@@ -3645,5 +3640,112 @@ namespace Hotline.Api.Controllers.Bi
 
             return ExcelStreamResult(stream, "未签收统计明细数据");
         }
+
+        /// <summary>
+        /// 企业专席信件统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("get_enterprise_seats_report")]
+        public async Task<object> GetEnterpriseSeatsReport([FromQuery] EnterpriseSeatsReportRequestDto dto)
+        {
+            var items = await _orderReportApplication.GetEnterpriseSeatsReport(dto);
+
+            var total = new EnterpriseSeatsReportDto
+            {
+                UserName = "合计",
+                UserId = "",
+                UserNo = "",
+                TelCallNum = items.Sum(p => p.TelCallNum),
+                OrderNum = items.Sum(p => p.OrderNum),
+            };
+
+            return new { List = items, Total = total };
+        }
+
+        /// <summary>
+        /// 企业专席信件统计--导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("get_enterprise_seats_report_export")]
+        public async Task<FileStreamResult> ExportGetEnterpriseSeatsReport([FromBody] ExportExcelDto<EnterpriseSeatsReportRequestDto> dto)
+        {
+            var list = await _orderReportApplication.GetEnterpriseSeatsReport(dto.QueryDto);
+
+            //增加合计
+            list.Add(new EnterpriseSeatsReportDto
+            {
+                UserName = "合计",
+                UserId = "",
+                UserNo = "",
+                TelCallNum = list.Sum(p => p.TelCallNum),
+                OrderNum = list.Sum(p => p.OrderNum),
+            });
+
+            var orderDtos = _mapper.Map<ICollection<EnterpriseSeatsReportDto>>(list);
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = orderDtos
+                .Select(stu => _mapper.Map(stu, typeof(EnterpriseSeatsReportDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "企业专席信件统计");
+        }
+
+        /// <summary>
+        /// 企业专席信件统计--明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("get_enterprise_seats_report_detail")]
+        public async Task<PagedDto<OrderDto>> GetEnterpriseSeatsReportDetail([FromQuery] EnterpriseSeatsReportRequestDto dto)
+        {
+            RefAsync<int> total = 0;
+            var queryData = await _orderReportApplication.GetEnterpriseSeatsReportDetail(dto)
+                        .ToPageListAsync(dto.PageIndex, dto.PageSize, total, HttpContext.RequestAborted);
+
+            return new PagedDto<OrderDto>(total, _mapper.Map<List<OrderDto>>(queryData));
+        }
+
+
+        /// <summary>
+        /// 企业专席信件统计--明细--导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("get_enterprise_seats_report_detail_export")]
+        public async Task<FileStreamResult> ExportGetEnterpriseSeatsReportDetail([FromBody] ExportExcelDto<EnterpriseSeatsReportRequestDto> dto)
+        {
+            var query = _orderReportApplication.GetEnterpriseSeatsReportDetail(dto.QueryDto);
+
+            List<OrderDto> list = new();
+            if (dto.IsExportAll)
+            {
+                var listData = await query.ToListAsync(HttpContext.RequestAborted);
+                list = _mapper.Map<List<OrderDto>>(listData);
+            }
+            else
+            {
+                RefAsync<int> total = 0;
+                var listData = await query.ToPageListAsync(dto.QueryDto.PageIndex, dto.QueryDto.PageSize, total, HttpContext.RequestAborted);
+                list = _mapper.Map<List<OrderDto>>(listData);
+            }
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = list
+                .Select(stu => _mapper.Map(stu, typeof(OrderDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "企业专席信件统计");
+        }
     }
 }

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

@@ -133,5 +133,19 @@ namespace Hotline.Application.StatisticalReport
         /// <param name="dto"></param>
         /// <returns></returns>
         ISugarQueryable<Order> GetOrderNoSigenDetail(OrderNoSigenRequestDto dto);
+
+        /// <summary>
+        /// 企业专席信件统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        Task<List<EnterpriseSeatsReportDto>> GetEnterpriseSeatsReport(EnterpriseSeatsReportRequestDto dto);
+
+        /// <summary>
+        /// 企业专席信件统计--明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        ISugarQueryable<Order> GetEnterpriseSeatsReportDetail(EnterpriseSeatsReportRequestDto dto);
     }
 }

+ 93 - 3
src/Hotline.Application/StatisticalReport/OrderReportApplication.cs

@@ -1,17 +1,21 @@
 using Hotline.Application.Orders;
 using Hotline.Caching.Interfaces;
 using Hotline.Caching.Services;
+using Hotline.CallCenter.Calls;
 using Hotline.FlowEngine.WorkflowModules;
 using Hotline.FlowEngine.Workflows;
+using Hotline.Identity.Accounts;
 using Hotline.Orders;
 using Hotline.Settings;
 using Hotline.Settings.TimeLimits;
 using Hotline.Share.Dtos.Bi;
 using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.Order;
+using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Requests;
+using Hotline.Users;
 using JiebaNet.Segmenter.Common;
 using MapsterMapper;
 using MediatR;
@@ -40,6 +44,9 @@ namespace Hotline.Application.StatisticalReport
         private readonly IOrderSecondaryHandlingApplication _orderSecondaryHandlingApplication;
         private readonly ITimeLimitDomainService _timeLimitDomainService;
         private readonly IRepository<SystemDicData> _systemDicDataRepository;
+        private readonly IRepository<TrCallRecord> _trCallRecordRepository;
+        private readonly ISystemSettingCacheManager _systemSettingCacheManager;
+        private readonly IRepository<User> _userRepository;
 
         /// <summary>
         /// 
@@ -65,9 +72,11 @@ namespace Hotline.Application.StatisticalReport
             IRepository<OrderScreen> orderScreenRepository,
             IOrderSecondaryHandlingApplication orderSecondaryHandlingApplication,
             ITimeLimitDomainService timeLimitDomainService,
-            IRepository<SystemDicData> systemDicDataRepository
-,
-            ISystemDicDataCacheManager sysDicDataCacheManager
+            IRepository<SystemDicData> systemDicDataRepository,
+            ISystemDicDataCacheManager sysDicDataCacheManager,
+            IRepository<TrCallRecord> trCallRecordRepository,
+            ISystemSettingCacheManager systemSettingCacheManager,
+            IRepository<User> userRepository
             )
         {
             _orderRepository = orderRepository;
@@ -82,6 +91,9 @@ namespace Hotline.Application.StatisticalReport
             _timeLimitDomainService = timeLimitDomainService;
             _systemDicDataRepository = systemDicDataRepository;
             _sysDicDataCacheManager = sysDicDataCacheManager;
+            _trCallRecordRepository = trCallRecordRepository;
+            _systemSettingCacheManager = systemSettingCacheManager;
+            _userRepository = userRepository;
         }
         /// <summary>
         /// 部门办件统计表---新
@@ -1862,5 +1874,83 @@ namespace Hotline.Application.StatisticalReport
                   .MergeTable();
             }
         }
+
+        /// <summary>
+        /// 企业专席信件统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        public async Task<List<EnterpriseSeatsReportDto>> GetEnterpriseSeatsReport(EnterpriseSeatsReportRequestDto dto)
+        {
+            dto.EndTime = dto.EndTime.AddDays(1).AddSeconds(-1);
+
+            var enterpriseSeats = _systemSettingCacheManager.GetSetting(SettingConstants.EnterpriseSeats)?.SettingValue;
+            //查询坐席信息
+            var userData = await _userRepository.Queryable()
+                  .Includes(p => p.Account)
+                  .Where(p => enterpriseSeats.Contains(p.Account.UserName)).ToListAsync();
+
+            //查询工单
+            var queryOrderData = _userRepository.Queryable()
+                  .Includes(u => u.Account)
+                  .Where(u => enterpriseSeats.Contains(u.Account.UserName))
+                  .MergeTable()
+                  .LeftJoin<Order>((u, o) => u.Id == o.SignerId)
+                   .Where((u, o) => o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime)
+                   .WhereIF(!string.IsNullOrEmpty(dto.UserName), (u, o) => o.SignerName.Contains(dto.UserName))
+                   .GroupBy((u, o) => new { o.SignerId, o.SignerName, u.StaffNo })
+                   .Select((u, o) => new EnterpriseSeatsReportDto
+                   {
+                       UserName = o.SignerName,
+                       UserId = o.SignerId,
+                       UserNo = u.StaffNo,
+                       TelCallNum = 0,
+                       OrderNum = SqlFunc.AggregateSum(SqlFunc.IIF(o.AcceptType != "无效", 1, 0)),
+                   }).MergeTable();
+
+            //查询通话
+            var queryCall = _userRepository.Queryable()
+                  .Includes(u => u.Account).Where(u => enterpriseSeats.Contains(u.Account.UserName)).MergeTable()
+                  .LeftJoin<TrCallRecord>((u, t) => u.Id == t.UserId)
+                  .Where((u, t) => t.CreatedTime >= dto.StartTime && t.CreatedTime <= dto.EndTime)
+                  .WhereIF(!string.IsNullOrEmpty(dto.UserName), (u, t) => t.UserName.Contains(dto.UserName))
+                  .GroupBy((u, t) => new { t.UserName, t.UserId, u.StaffNo })
+                  .Select((u, t) => new EnterpriseSeatsReportDto
+                  {
+                      UserName = t.UserName,
+                      UserId = t.UserId,
+                      UserNo = u.StaffNo,
+                      TelCallNum = SqlFunc.AggregateSum(SqlFunc.IIF(t.CallDirection == ECallDirection.In || t.CallDirection == ECallDirection.Out, 1, 0)),
+                      OrderNum = 0
+                  }).MergeTable();
+
+            return await _orderRepository.UnionAll(queryOrderData, queryCall).GroupBy(p => new { p.UserNo, p.UserId, p.UserName })
+                    .Select(p => new EnterpriseSeatsReportDto
+                    {
+                        UserName = p.UserName,
+                        UserId = p.UserId,
+                        UserNo = p.UserNo,
+                        TelCallNum = SqlFunc.AggregateSum(p.TelCallNum),
+                        OrderNum = SqlFunc.AggregateSum(p.OrderNum),
+                    })
+                    .ToListAsync();
+
+        }
+
+        /// <summary>
+        /// 企业专席信件统计--明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        public ISugarQueryable<Order> GetEnterpriseSeatsReportDetail(EnterpriseSeatsReportRequestDto dto)
+        {
+            dto.EndTime = dto.EndTime.AddDays(1).AddSeconds(-1);
+
+            return _orderRepository.Queryable()
+                  .Where(o => o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime && o.SignerId == dto.UserId)
+                  .WhereIF(!string.IsNullOrEmpty(dto.UserName), o => o.SignerName.Contains(dto.UserName))
+               .OrderByDescending(o => o.CreationTime);
+
+        }
     }
 }

+ 27 - 0
src/Hotline.Share/Dtos/Bi/EnterpriseSeatsReportDto.cs

@@ -0,0 +1,27 @@
+namespace Hotline.Share.Dtos.Bi
+{
+    public class EnterpriseSeatsReportDto
+    {
+        /// <summary>
+        /// 坐席名称
+        /// </summary>
+        public string UserName { get; set; }
+
+        public string UserId { get; set; }
+
+        /// <summary>
+        /// 坐席工号
+        /// </summary>
+        public string UserNo { get; set; }
+
+        /// <summary>
+        /// 话务量
+        /// </summary>
+        public int TelCallNum { get; set; }
+
+        /// <summary>
+        /// 工单量
+        /// </summary>
+        public int OrderNum { get; set; }
+    }
+}

+ 24 - 0
src/Hotline.Share/Requests/OrderNoSigenRequestDto.cs

@@ -37,4 +37,28 @@
         /// </summary>
         public int? DataSoure { get; set; }
     }
+
+
+    public record EnterpriseSeatsReportRequestDto : PagedRequest
+    {
+        /// <summary>
+        /// 开始时间
+        /// </summary>
+        public DateTime StartTime { get; set; }
+
+        /// <summary>
+        /// 结束时间
+        /// </summary>
+        public DateTime EndTime { get; set; }
+
+        /// <summary>
+        /// 坐席名称
+        /// </summary>
+        public string? UserName { get; set; }
+
+        /// <summary>
+        /// 坐席Id
+        /// </summary>
+        public string? UserId { get; set;}
+    }
 }

+ 5 - 0
src/Hotline/Settings/SettingConstants.cs

@@ -459,5 +459,10 @@ namespace Hotline.Settings
         /// 录音地址下载前缀
         /// </summary>
         public const string RecordDownLoadPrefix = "RecordDownLoadPrefix";
+
+        /// <summary>
+        /// 企业专席配置	
+        /// </summary>
+        public const string EnterpriseSeats = "EnterpriseSeats";
     }
 }