qinchaoyue 8 kuukautta sitten
vanhempi
commit
04d527bae0

+ 250 - 47
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -55,7 +55,7 @@ namespace Hotline.Api.Controllers.Bi
         private readonly IRepository<OrderSpecialDetail> _orderSpecialDetailRepository;
         private readonly IRepository<WorkflowTrace> _workflowTraceRepository;
         private readonly IRepository<WorkflowStep> _workflowStepRepository;
-		private readonly IRepository<OrderScreen> _orderScreenRepository;
+        private readonly IRepository<OrderScreen> _orderScreenRepository;
         private readonly IOrderSecondaryHandlingApplication _orderSecondaryHandlingApplication;
         private readonly IOrderApplication _orderApplication;
         private readonly ITimeLimitDomainService _timeLimitDomainService;
@@ -123,7 +123,7 @@ namespace Hotline.Api.Controllers.Bi
             _systemDicDataCacheManager = systemDicDataCacheManager;
             _workflowStepRepository = workflowStepRepository;
 
-		}
+        }
 
         /// <summary>
         /// 部门超期统计明细
@@ -2312,7 +2312,7 @@ namespace Hotline.Api.Controllers.Bi
                 .Where((x, su) => x.CreationTime >= dto.StartTime.Value && x.CreationTime <= dto.EndTime.Value && su.UserId == dto.UserId)
                 .WhereIF(dto.TitleCode.ToUpper() == "NOSENDORDERNUM", (x, su) => x.Status != EWorkflowStepStatus.Handled)
                 .WhereIF(dto.TitleCode.ToUpper() == "SENDORDERNUM", (x, su) => x.Status == EWorkflowStepStatus.Handled)
-				.GroupBy((x, su) => x.ExternalId)
+                .GroupBy((x, su) => x.ExternalId)
                 .Select((x, su) => new { Id = x.ExternalId })
                 .MergeTable()
                 .LeftJoin<Order>((a, b) => a.Id == b.Id)
@@ -3382,65 +3382,268 @@ namespace Hotline.Api.Controllers.Bi
         public async Task<object> HotspotAndAcceptTypeStatistics([FromQuery] HotspotAndAcceptTypeStatisticsReq dto)
         {
 
-	        var (areaList, returnList) = await _orderApplication.HotspotAndAcceptTypeStatistics(dto);
+            var (areaList, returnList) = await _orderApplication.HotspotAndAcceptTypeStatistics(dto);
 
-	        return new { AreaList = areaList, Data = returnList };
+            return new { AreaList = areaList, Data = returnList };
         }
 
-		/// <summary>
-		/// 热点受理类型统计导出
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpPost("hotspot-accepttype-statistics-export")]
+        /// <summary>
+        /// 热点受理类型统计导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("hotspot-accepttype-statistics-export")]
         public async Task<FileStreamResult> HotspotAndAcceptTypeStatisticsExport([FromBody] HotspotAndAcceptTypeStatisticsReq dto)
         {
-	        var returnList = await _orderApplication.HotspotAndAcceptTypeStatisticsExport(dto);
-	        var table = _orderApplication.InitHotspotTable(returnList, dto.AddColumnName, dto.HotspotLevel);
-	        var stream = ExcelHelper.CreateStream(table);
-	        return ExcelStreamResult(stream, "热点受理类型统计");
+            var returnList = await _orderApplication.HotspotAndAcceptTypeStatisticsExport(dto);
+            var table = _orderApplication.InitHotspotTable(returnList, dto.AddColumnName, dto.HotspotLevel);
+            var stream = ExcelHelper.CreateStream(table);
+            return ExcelStreamResult(stream, "热点受理类型统计");
+        }
+
+        /// <summary>
+        /// 热点受理类型明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("hotspot-accepttype-statistics-detail")]
+        public async Task<PagedDto<OrderDto>> HotspotAndAcceptTypeStatisticsDetail([FromQuery] HotspotAndAcceptTypeStatisticsDetailReq dto)
+        {
+            var (total, items) = await _orderApplication.HotspotAndAcceptTypeStatisticsDetail(dto).ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
+            return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
+        }
+        /// <summary>
+        /// 热点受理类型明细导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("hotspot-accepttype-statistics-detail-export")]
+        public async Task<FileStreamResult> HotspotAndAcceptTypeStatisticsDetailExport([FromBody] ExportExcelDto<HotspotAndAcceptTypeStatisticsDetailReq> dto)
+        {
+            var query = _orderApplication.HotspotAndAcceptTypeStatisticsDetail(dto.QueryDto);
+
+            List<Order> orders;
+            if (dto.IsExportAll)
+            {
+                orders = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+                orders = items;
+            }
+            var ordersDtos = _mapper.Map<ICollection<OrderDto>>(orders);
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+            var dtos = ordersDtos
+                .Select(stu => _mapper.Map(stu, typeof(OrderDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+            return ExcelStreamResult(stream, "热点受理类型明细");
         }
 
 		/// <summary>
-		/// 热点受理类型明细
+		/// 甄别申请统计
 		/// </summary>
 		/// <param name="dto"></param>
 		/// <returns></returns>
-		[HttpGet("hotspot-accepttype-statistics-detail")]
-        public async Task<PagedDto<OrderDto>> HotspotAndAcceptTypeStatisticsDetail([FromQuery] HotspotAndAcceptTypeStatisticsDetailReq dto)
-        {
-	        var (total, items) = await _orderApplication.HotspotAndAcceptTypeStatisticsDetail(dto).ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
-	        return  new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
+		[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>
-		[HttpPost("hotspot-accepttype-statistics-detail-export")]
-        public async Task<FileStreamResult> HotspotAndAcceptTypeStatisticsDetailExport([FromBody] ExportExcelDto<HotspotAndAcceptTypeStatisticsDetailReq> dto)
+		[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("get_order_nosigen")]
+        public async Task<object> GetOrderNoSigen([FromQuery] OrderNoSigenRequestDto dto)
+        {
+            var items = await _orderReportApplication.GetOrderNoSigen(dto);
+
+            var total = new OrderNoSigenDto
+            {
+                OrgName = "合计",
+                OrgCode = "",
+                OrderNoSigen = items.Sum(p => p.OrderNoSigen),
+                CounterNoSign = items.Sum(p => p.CounterNoSign)
+            };
+
+            return new { List = items, Total = total };
+        }
+
+        /// <summary>
+        /// 未签收统计--导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("get_order_nosigen_export")]
+        public async Task<FileStreamResult> ExportGetOrderNoSigen([FromBody] ExportExcelDto<OrderNoSigenRequestDto> dto)
         {
-	        var query = _orderApplication.HotspotAndAcceptTypeStatisticsDetail(dto.QueryDto);
-
-	        List<Order> orders;
-	        if (dto.IsExportAll)
-	        {
-		        orders = await query.ToListAsync(HttpContext.RequestAborted);
-	        }
-	        else
-	        {
-		        var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
-		        orders = items;
-	        }
-	        var ordersDtos = _mapper.Map<ICollection<OrderDto>>(orders);
-	        dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
-	        var dtos = ordersDtos
-		        .Select(stu => _mapper.Map(stu, typeof(OrderDto), dynamicClass))
-		        .Cast<object>()
-		        .ToList();
-
-	        var stream = ExcelHelper.CreateStream(dtos);
-	        return ExcelStreamResult(stream, "热点受理类型明细");
-        }
-	}
+            var list = await _orderReportApplication.GetOrderNoSigen(dto.QueryDto);
+
+            //增加合计
+            list.Add(new OrderNoSigenDto
+            {
+                OrgName = "合计",
+                OrgCode = "",
+                OrderNoSigen = list.Sum(p => p.OrderNoSigen),
+                CounterNoSign = list.Sum(p => p.CounterNoSign)
+            });
+
+            var orderDtos = _mapper.Map<ICollection<OrderNoSigenDto>>(list);
+
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = orderDtos
+                .Select(stu => _mapper.Map(stu, typeof(OrderNoSigenDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "未签收统计数据");
+        }
+
+        /// <summary>
+        /// 未签收统计--明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("get_order_nosigen_detail")]
+        public async Task<PagedDto<OrderDto>> GetOrderNoSigenDetail([FromQuery] OrderNoSigenRequestDto dto)
+        {
+            RefAsync<int> total = 0;
+
+            var queryData = await _orderReportApplication.GetOrderNoSigenDetail(dto)
+                         .Select(o => new { o })
+                        .ToPageListAsync(dto.PageIndex, dto.PageSize, total, HttpContext.RequestAborted);
+
+            var dtos = queryData.Select(d =>
+            {
+                var dto = _mapper.Map<OrderDto>(d.o);
+                return dto;
+            }).ToList();
+            return new PagedDto<OrderDto>(total, dtos);
+        }
+
+        /// <summary>
+        /// 未签收统计--明细--导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("get_order_nosigen_detail_export")]
+        public async Task<FileStreamResult> ExportGetOrderNoSigenDetail([FromBody] ExportExcelDto<OrderNoSigenRequestDto> dto)
+        {
+            var query = _orderReportApplication.GetOrderNoSigenDetail(dto.QueryDto).Select(o => new { o });
+
+            List<OrderDto> list = new();
+            if (dto.IsExportAll)
+            {
+                var listData = await query.ToListAsync(HttpContext.RequestAborted);
+                list = listData.Select(d =>
+                {
+                    var dto = _mapper.Map<OrderDto>(d.o);
+                    return dto;
+                }).ToList();
+            }
+            else
+            {
+                RefAsync<int> total = 0;
+                var listData = await query.ToPageListAsync(dto.QueryDto.PageIndex, dto.QueryDto.PageSize, total, HttpContext.RequestAborted);
+                list = listData.Select(d =>
+                {
+                    var dto = _mapper.Map<OrderDto>(d.o);
+                    return dto;
+                }).ToList();
+            }
+
+            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, "未签收统计明细数据");
+        }
+    }
 }

+ 38 - 3
src/Hotline.Api/Controllers/IdentityController.cs

@@ -105,7 +105,7 @@ jxrWXHbT1FB6DqkdOnBbQqS1Azqz5HxLlSyEK3F60e3SgB5iZsDZ
     [HttpGet("login-page-info")]
     public async Task<LoginPageInfoDto> LoginPageInfo()
     {
-        var SysName = _systemSettingCacheManager.GetSetting(SettingConstants.SysName).SettingValue;
+        var SysName = _systemSettingCacheManager.GetSetting(SettingConstants.SysName).SettingValue?.FirstOrDefault();
         var loginImage = _systemSettingCacheManager.GetSetting(SettingConstants.LoginImage).SettingValue?.FirstOrDefault();
         var changePwdImage = _systemSettingCacheManager.GetSetting(SettingConstants.ChangePwdImage).SettingValue?.FirstOrDefault();
         var faviconImage = _systemSettingCacheManager.GetSetting(SettingConstants.FaviconImage).SettingValue?.FirstOrDefault();
@@ -113,10 +113,45 @@ jxrWXHbT1FB6DqkdOnBbQqS1Azqz5HxLlSyEK3F60e3SgB5iZsDZ
         var menuLogoImageMini = _systemSettingCacheManager.GetSetting(SettingConstants.MenuLogoImageMini).SettingValue?.FirstOrDefault();
         var IsLoginMessageCode = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsLoginMessageCode).SettingValue[0]);
 
+        var recordPrefix = _systemSettingCacheManager.GetSetting(SettingConstants.RecordPrefix).SettingValue?.FirstOrDefault();
+        var recordDownLoadPrefix = _systemSettingCacheManager.GetSetting(SettingConstants.RecordDownLoadPrefix).SettingValue?.FirstOrDefault();
+        var callCenterSocketUrl =_systemSettingCacheManager.GetSetting(SettingConstants.CallCenterSocketUrl).SettingValue?.FirstOrDefault();
+        double[] locationCenter = new double[2];
+        try
+        {
+            locationCenter = _systemSettingCacheManager
+                .GetSetting(SettingConstants.LocationCenter)
+                .SettingValue?
+                .FirstOrDefault()
+                .Split(',')
+                .Select(double.Parse)
+                .ToArray();
+        }
+        catch (Exception e)
+        {
+            // ignore
+        }
+        var recordNumber = _systemSettingCacheManager.GetSetting(SettingConstants.RecordNumber).SettingValue?.FirstOrDefault();
+        var cityAbbr = _systemSettingCacheManager.GetSetting(SettingConstants.CityAbbr).SettingValue?.FirstOrDefault();
+        var operate = _systemSettingCacheManager.GetSetting(SettingConstants.Operate).SettingValue?.FirstOrDefault();
+        var techSupport = _systemSettingCacheManager.GetSetting(SettingConstants.TechSupport).SettingValue?.FirstOrDefault();
+        var cityCode = _systemSettingCacheManager.GetSetting(SettingConstants.CityCode).SettingValue?.FirstOrDefault();
+        var cityName = _systemSettingCacheManager.GetSetting(SettingConstants.CityName).SettingValue?.FirstOrDefault();
+
         return new LoginPageInfoDto
         {
-            SysName = SysName, 
-            LoginImage = loginImage, 
+            CityAbbr = cityAbbr,
+            LocationCenter = locationCenter,
+            CityName = cityName,
+            CityCode = cityCode,
+            TechSupport = techSupport,
+            Operate = operate,
+            RecordNumber = recordNumber,
+            CallCenterSocketUrl = callCenterSocketUrl,
+            RecordDownLoadPrefix = recordDownLoadPrefix,
+            RecordPrefix = recordPrefix,
+            SysName = SysName,
+            LoginImage = loginImage,
             ChangPwdImage = changePwdImage,
             FaviconImage = faviconImage,
             MenuLogoImage = menuLogoImage,

+ 44 - 0
src/Hotline.Api/Controllers/OrderController.cs

@@ -747,6 +747,50 @@ public class OrderController : BaseController
 
     #region 工单回访
 
+    /// <summary>
+    /// 回访来源统计
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet("visit/source")]
+    [AllowAnonymous]
+    public async Task<IList<OrderVisitSourceChannelDto>> QueryOrderVisitSourceChannelAsync([FromQuery] QueryOrderVisitSourceChannelDto dto)
+    {
+        var startDate = new DateTime();
+        var endDate = new DateTime();
+        switch (dto.DateType)
+        {
+            case Share.Enums.Order.EDateType.Day:
+                (startDate, endDate) = dto.StartTime.GetDayStartAndEnd();
+                break;
+            case Share.Enums.Order.EDateType.Week:
+                (startDate, endDate) = dto.StartTime.GetWeekStartAndEnd();
+                break;
+            case Share.Enums.Order.EDateType.Month:
+                (startDate, endDate) = dto.StartTime.GetMonthStartAndEnd();
+                break;
+            case Share.Enums.Order.EDateType.TimeLimit:
+                if (dto.EndTime is null) throw new UserFriendlyException("结束时间错误");
+                startDate = dto.StartTime;
+                endDate = dto.EndTime.Value;
+                break;
+            default:
+                break;
+        }
+
+        var result = await _orderVisitRepository.Queryable()
+            .LeftJoin<Order>((visit, order) => order.Id == visit.OrderId)
+            .Where((visit, order) => visit.VisitTime >= startDate && visit.VisitTime <= endDate)
+            .GroupBy((visit, order) => new { order.SourceChannel })
+            .Select((visit, order) => new OrderVisitSourceChannelDto
+            {
+                Count = SqlFunc.AggregateCount(visit.OrderId),
+                SourceChannel = order.SourceChannel
+            })
+            .ToListAsync();
+
+        return result;
+    }
+
     /// <summary>
     /// 回访列表
     /// </summary>

+ 2 - 2
src/Hotline.Api/config/appsettings.Development.json

@@ -65,7 +65,7 @@
     "Host": "110.188.24.182",
     "Port": 50179,
     "Password": "fengwo123!$!$",
-    "Database": 3 //release:3, dev:5
+    "Database": 5 //release:3, dev:5
   },
   "Swagger": true,
   "Cors": {
@@ -100,7 +100,7 @@
     }
   },
   "DatabaseConfiguration": {
-    "ApplyDbMigrations": true,
+    "ApplyDbMigrations": false,
     "ApplySeed": false
   },
   "MqConfiguration": {

+ 14 - 0
src/Hotline.Application/Orders/IOrderApplication.cs

@@ -224,5 +224,19 @@ namespace Hotline.Application.Orders
         /// <returns></returns>
         ISugarQueryable<Order> HotspotAndAcceptTypeStatisticsDetail(HotspotAndAcceptTypeStatisticsDetailReq dto);
 
+        /// <summary>
+        /// 甄别申请统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        ISugarQueryable<OrderScreenApplyVo> OrderScreenApply(OrderScreenApplyPagedRequest dto);
+
+        /// <summary>
+        /// 甄别审批统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        ISugarQueryable<OrderScreenAuditVo> OrderScreenAudit(OrderScreenAuditPagedRequest dto);
+
 	}
 }

+ 53 - 2
src/Hotline.Application/Orders/OrderApplication.cs

@@ -76,6 +76,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     private readonly IRepository<WorkflowStep> _workflowStepRepository;
     private readonly IRepository<WorkflowTrace> _workflowTraceRepository;
     private readonly IRepository<SystemDicData> _systemDicDataRepository;
+    private readonly IRepository<OrderScreen> _orderScreenRepository;
 
 
 	public OrderApplication(
@@ -100,7 +101,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         IRepository<Hotspot> hotspotRepository,
         IRepository<WorkflowStep> workflowStepRepository,
         IRepository<SystemDicData> systemDicDataRepository,
-        IRepository<WorkflowTrace> workflowTraceRepository)
+        IRepository<WorkflowTrace> workflowTraceRepository,
+        IRepository<OrderScreen> orderScreenRepository)
     {
         _orderDomainService = orderDomainService;
         _workflowDomainService = workflowDomainService;
@@ -124,7 +126,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         _workflowStepRepository = workflowStepRepository;
         _systemDicDataRepository = systemDicDataRepository;
         _workflowTraceRepository = workflowTraceRepository;
-    }
+        _orderScreenRepository = orderScreenRepository;
+
+	}
 
     /// <summary>
     /// 更新工单办理期满时间(延期调用,其他不调用)
@@ -1607,6 +1611,53 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 		return query;
 	}
 
+    /// <summary>
+    /// 甄别申请统计
+    /// </summary>
+    /// <returns></returns>
+	public ISugarQueryable<OrderScreenApplyVo> OrderScreenApply(OrderScreenApplyPagedRequest dto)
+	{
+		if (dto.EndTime.HasValue)
+		    dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
+        var query = _orderScreenRepository.Queryable()
+            .WhereIF(dto.StartTime.HasValue && dto.EndTime.HasValue, x => x.CreationTime >= dto.StartTime && x.CreationTime <= dto.EndTime)
+            .WhereIF(!string.IsNullOrEmpty(dto.ApplyUserName),x=> x.CreatorName == dto.ApplyUserName)
+            .WhereIF(!string.IsNullOrEmpty(dto.ApplyOrgName), x => x.CreatorOrgName == dto.ApplyOrgName)
+			.GroupBy(x => new { ApplyTime = x.CreationTime.ToString("yyyy-MM-dd"), x.CreatorName, x.CreatorOrgName })
+            .Select(x => new OrderScreenApplyVo
+            {
+                ApplyTime = x.CreationTime.ToString("yyyy-MM-dd"),
+                ApplyUserName = x.CreatorName,
+                ApplyOrgName = x.CreatorOrgName,
+                ApplyNum = SqlFunc.AggregateCount(1)
+            });
+		return query;
+	}
+
+    /// <summary>
+    /// 甄别审批统计
+    /// </summary>
+    /// <returns></returns>
+    public ISugarQueryable<OrderScreenAuditVo> OrderScreenAudit(OrderScreenAuditPagedRequest dto)
+    {
+	    if (dto.EndTime.HasValue)
+		    dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
+	    var query = _workflowTraceRepository.Queryable()
+		    .WhereIF(dto.StartTime.HasValue && dto.EndTime.HasValue, x => x.HandleTime >= dto.StartTime && x.HandleTime <= dto.EndTime)
+		    .WhereIF(!string.IsNullOrEmpty(dto.AuditUserName), x => x.HandlerName == dto.AuditUserName)
+            .Where(x=> x.HandlerName != null && x.HandlerName != "" && x.Status == EWorkflowStepStatus.Handled)
+            .WhereIF(dto.AuditType is 1,x=>x.Name == "班长审批")
+		    .WhereIF(dto.AuditType is 2, x => x.Name == "中心领导")
+			.GroupBy(x => new { x.HandlerName })
+		    .Select(x => new OrderScreenAuditVo
+			{
+			  AuditName = x.HandlerName,
+              AuditNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.TraceState  == EWorkflowTraceState.Normal, 1, 0)),
+              AuditBackNum = SqlFunc.AggregateSum(SqlFunc.IIF( x.TraceState != EWorkflowTraceState.Normal, 1, 0)),
+			});
+	    return query;
+    }
+
 	#region private
 
 	/// <summary>

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

@@ -119,5 +119,19 @@ namespace Hotline.Application.StatisticalReport
         /// <param name="list"></param>
         /// <returns></returns>
         Task<DataTable> ExportQueryVisitNoSatisfiedAsync(IReadOnlyList<SystemDicData> dissatisfiedReason, List<dynamic>? list, List<string> addColumnName);
+
+        /// <summary>
+        /// 未签收统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        Task<List<OrderNoSigenDto>> GetOrderNoSigen(OrderNoSigenRequestDto dto);
+
+        /// <summary>
+        /// 未签收统计--明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        ISugarQueryable<Order> GetOrderNoSigenDetail(OrderNoSigenRequestDto dto);
     }
 }

+ 118 - 2
src/Hotline.Application/StatisticalReport/OrderReportApplication.cs

@@ -16,6 +16,7 @@ using JiebaNet.Segmenter.Common;
 using MapsterMapper;
 using MediatR;
 using Microsoft.IdentityModel.Tokens;
+using NPOI.SS.Formula.Functions;
 using SqlSugar;
 using System.Data;
 using XF.Domain.Authentications;
@@ -1574,7 +1575,6 @@ namespace Hotline.Application.StatisticalReport
                  .MergeTable();
         }
 
-
         /// <summary>
         /// 满意度明细
         /// </summary>
@@ -1605,7 +1605,6 @@ namespace Hotline.Application.StatisticalReport
 
         }
 
-
         /// <summary>
         /// 受理类型统计
         /// </summary>
@@ -1746,5 +1745,122 @@ namespace Hotline.Application.StatisticalReport
             }
             return dataTable;
         }
+
+        /// <summary>
+        /// 未签收统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        public async Task<List<OrderNoSigenDto>> GetOrderNoSigen(OrderNoSigenRequestDto dto)
+        {
+            dto.EndTime = dto.EndTime.AddDays(1).AddSeconds(-1);
+
+            var isCenter = _sessionContext.OrgIsCenter;
+            //工单未超期
+            var queryOrderNoSigen = _orderRepository.Queryable()
+               .LeftJoin<WorkflowStep>((o, w) => o.Id == w.ExternalId)
+               .Where((o, w) => o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime && w.ModuleCode == WorkflowModuleConsts.OrderHandle
+                       && w.Status == EWorkflowStepStatus.WaitForAccept && w.CountersignPosition == ECountersignPosition.None)
+               .WhereIF(dto.IsProvince.HasValue && dto.IsProvince == true, (o, w) => o.Source == ESource.ProvinceStraight)
+               .WhereIF(dto.TypeId != null && dto.TypeId == 1, (o, w) => o.IdentityType == EIdentityType.Citizen)
+               .WhereIF(dto.TypeId != null && dto.TypeId == 2, (o, w) => o.IdentityType == EIdentityType.Enterprise)
+               .Select((o, w) => new
+               {
+                   OrgCode = isCenter == true ? w.HandlerOrgId.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")) : w.HandlerOrgId.Substring(0, _sessionContext.RequiredOrgId.Length + 3),
+               })
+               .MergeTable()
+               .LeftJoin<SystemOrganize>((it, sy) => it.OrgCode == sy.Id)
+                // .WhereIF(!string.IsNullOrEmpty(dto.OrgName), (it, sy) => sy.Name.Contains(dto.OrgName))
+                .GroupBy((it, sy) => new
+                {
+                    it.OrgCode,
+                    sy.Name,
+                })
+                 .Select((it, sy) => new OrderNoSigenDto
+                 {
+                     OrgName = it.OrgCode == "001" ? "市民热线服务中心" : sy.Name,
+                     OrgCode = it.OrgCode,
+                     OrderNoSigen = SqlFunc.AggregateSum(1),
+                     CounterNoSign = 0
+                 }).MergeTable();
+
+            //会签未签收
+            var queryCounterNoSign = _orderRepository.Queryable()
+                .LeftJoin<WorkflowStep>((o, w) => o.Id == w.ExternalId)
+                .Where((o, w) => w.CreationTime >= dto.StartTime && w.CreationTime <= dto.EndTime && w.ModuleCode == WorkflowModuleConsts.OrderHandle
+                        && w.Status == EWorkflowStepStatus.WaitForAccept && w.CountersignPosition > ECountersignPosition.None)
+                .WhereIF(dto.IsProvince.HasValue && dto.IsProvince == true, (o, w) => o.Source == ESource.ProvinceStraight)
+                .WhereIF(dto.TypeId != null && dto.TypeId == 1, (o, w) => o.IdentityType == EIdentityType.Citizen)
+                .WhereIF(dto.TypeId != null && dto.TypeId == 2, (o, w) => o.IdentityType == EIdentityType.Enterprise)
+                .Select((o, w) => new
+                {
+                    OrgCode = isCenter == true ? w.HandlerOrgId.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")) : w.HandlerOrgId.Substring(0, _sessionContext.RequiredOrgId.Length + 3),
+                })
+                .MergeTable()
+                .LeftJoin<SystemOrganize>((it, sy) => it.OrgCode == sy.Id)
+                 //  .WhereIF(!string.IsNullOrEmpty(dto.OrgName), (it, sy) => sy.Name.Contains(dto.OrgName))
+                 .GroupBy((it, sy) => new
+                 {
+                     it.OrgCode,
+                     sy.Name,
+                 })
+                  .Select((it, sy) => new OrderNoSigenDto
+                  {
+                      OrgName = it.OrgCode == "001" ? "市民热线服务中心" : sy.Name,
+                      OrgCode = it.OrgCode,
+                      OrderNoSigen = 0,
+                      CounterNoSign = SqlFunc.AggregateSum(1)
+                  }).MergeTable();
+
+            return await _orderRepository.UnionAll(queryOrderNoSigen, queryCounterNoSign).GroupBy(p => new { p.OrgCode, p.OrgName })
+                .Select(p => new OrderNoSigenDto
+                {
+                    OrgName = p.OrgName,
+                    OrgCode = p.OrgCode,
+                    OrderNoSigen = SqlFunc.AggregateSum(p.OrderNoSigen),
+                    CounterNoSign = SqlFunc.AggregateSum(p.CounterNoSign),
+                })
+                .ToListAsync();
+
+        }
+
+        /// <summary>
+        /// 未签收统计--明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        public ISugarQueryable<Order> GetOrderNoSigenDetail(OrderNoSigenRequestDto dto)
+        {
+            dto.EndTime = dto.EndTime.AddDays(1).AddSeconds(-1);
+
+            if (dto.DataSoure == 2)
+            {
+                //会签未签收
+                return _orderRepository.Queryable()
+                    .LeftJoin<WorkflowStep>((o, w) => o.Id == w.ExternalId)
+                    .Where((o, w) => w.CreationTime >= dto.StartTime && w.CreationTime <= dto.EndTime && w.ModuleCode == WorkflowModuleConsts.OrderHandle
+                            && w.Status == EWorkflowStepStatus.WaitForAccept && w.CountersignPosition > ECountersignPosition.None)
+                    .WhereIF(dto.IsProvince.HasValue && dto.IsProvince == true, (o, w) => o.Source == ESource.ProvinceStraight)
+                    .WhereIF(dto.TypeId != null && dto.TypeId == 1, (o, w) => o.IdentityType == EIdentityType.Citizen)
+                    .WhereIF(dto.TypeId != null && dto.TypeId == 2, (o, w) => o.IdentityType == EIdentityType.Enterprise)
+                    .WhereIF(dto.OrgCode == "001", (o, w) => w.HandlerOrgId == dto.OrgCode)
+                   .WhereIF(dto.OrgCode != "001", (o, w) => w.HandlerOrgId.StartsWith(dto.OrgCode))
+                   .MergeTable();
+            }
+            else
+            {
+                //工单未超期
+                return _orderRepository.Queryable()
+                    .LeftJoin<WorkflowStep>((o, w) => o.Id == w.ExternalId)
+                    .Where((o, w) => o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime && w.ModuleCode == WorkflowModuleConsts.OrderHandle
+                            && w.Status == EWorkflowStepStatus.WaitForAccept && w.CountersignPosition == ECountersignPosition.None)
+                    .WhereIF(dto.IsProvince.HasValue && dto.IsProvince == true, (o, w) => o.Source == ESource.ProvinceStraight)
+                    .WhereIF(dto.TypeId != null && dto.TypeId == 1, (o, w) => o.IdentityType == EIdentityType.Citizen)
+                    .WhereIF(dto.TypeId != null && dto.TypeId == 2, (o, w) => o.IdentityType == EIdentityType.Enterprise)
+                    .WhereIF(dto.OrgCode == "001", (o, w) => w.HandlerOrgId == dto.OrgCode)
+                    .WhereIF(dto.OrgCode != "001", (o, w) => w.HandlerOrgId.StartsWith(dto.OrgCode))
+                  .MergeTable();
+            }
+        }
     }
 }

+ 30 - 0
src/Hotline.Share/Dtos/Bi/OrderNoSigenDto.cs

@@ -0,0 +1,30 @@
+namespace Hotline.Share.Dtos.Bi
+{
+    public class OrderNoSigenDto
+    {
+        /// <summary>
+        /// 部门名称
+        /// </summary>
+        public string OrgName { get; set; }
+
+        /// <summary>
+        /// 部门Code
+        /// </summary>
+        public string OrgCode { get; set; }
+
+        /// <summary>
+        /// 工单未签收
+        /// </summary>
+        public int OrderNoSigen { get; set; }
+
+        /// <summary>
+        /// 会签未签收
+        /// </summary>
+        public int CounterNoSign { get; set; }
+
+        /// <summary>
+        /// 总量
+        /// </summary>
+        public int TotleNoSign => OrderNoSigen + CounterNoSign;
+    }
+}

+ 78 - 1
src/Hotline.Share/Dtos/Identity/LoginDto.cs

@@ -15,7 +15,6 @@ namespace Hotline.Share.Dtos.Identity
 
     public class LoginPageInfoDto
     {
-        public List<string> SysName { get; set; }
 
         /// <summary>
         /// 首页图片
@@ -37,6 +36,32 @@ namespace Hotline.Share.Dtos.Identity
         /// </summary>
         public string? MenuLogoImage{ get; set; }
 
+        /// <summary>
+        /// 菜单logo图片mini
+        /// </summary>
+        public string? MenuLogoImageMini { get; set; }
+        public string SysName { get; set; }
+
+        /// <summary>
+        /// 首页图片
+        /// </summary>
+        public string? LoginImage { get; set; }
+
+        /// <summary>
+        /// 修改密码图片
+        /// </summary>
+        public string? ChangPwdImage { get; set; }
+
+        /// <summary>
+        /// 角标图片
+        /// </summary>
+        public string? FaviconImage { get; set; }
+
+        /// <summary>
+        /// 菜单logo图片
+        /// </summary>
+        public string? MenuLogoImage { get; set; }
+
         /// <summary>
         /// 菜单logo图片mini
         /// </summary>
@@ -53,5 +78,57 @@ namespace Hotline.Share.Dtos.Identity
         /// 呼叫中心类型
         /// </summary>
         public string CallCenterType { get; set; }
+
+        /// <summary>
+        /// 城市中文名称
+        /// </summary>
+        public string CityName { get; set; }
+
+        /// <summary>
+        /// 城市Code
+        /// </summary>
+        public string CityCode { get; set; }
+
+        /// <summary>
+        /// 运营商名称
+        /// </summary>
+        public string Operate { get; set; }
+
+        /// <summary>
+        /// 技术支持
+        /// </summary>
+        public string TechSupport { get; set; }
+
+        /// <summary>
+        /// 城市简写
+        /// </summary>
+        public string CityAbbr { get; set; }
+
+        /// <summary>
+        /// 备案号
+        /// </summary>
+        public string RecordNumber { get; set; }
+
+        /// <summary>
+        /// 地图中心点
+        /// </summary>
+        public double[] LocationCenter { get; set; }
+
+        /// <summary>
+        /// 呼叫中心socket地址
+        /// </summary>
+        public string CallCenterSocketUrl { get; set; }
+
+        /// <summary>
+        /// 播放地址前缀
+        /// </summary>
+        public string RecordPrefix { get; set; }
+
+        /// <summary>
+        /// 下载地址前缀
+        /// </summary>
+        public string RecordDownLoadPrefix { get; set; }
     }
+
+
 }

+ 45 - 1
src/Hotline.Share/Dtos/Order/OrderBiDto.cs

@@ -1174,5 +1174,49 @@ namespace Hotline.Share.Dtos.Order
 	}
 
 
-    
+	public class OrderScreenApplyVo
+	{
+		/// <summary>
+		/// 提起时间
+		/// </summary>
+		public string ApplyTime { get; set; }
+
+		/// <summary>
+		/// 提起人
+		/// </summary>
+		public string ApplyUserName { get; set; }
+
+		/// <summary>
+		/// 部门名称
+		/// </summary>
+		public string ApplyOrgName { get; set; }
+
+		/// <summary>
+		/// 数量
+		/// </summary>
+		public int ApplyNum { get; set; }
+	}
+
+	public class OrderScreenAuditVo { 
+	
+		/// <summary>
+		/// 审批人
+		/// </summary>
+		public string AuditName { get; set; }
+
+		/// <summary>
+		/// 审批数量
+		/// </summary>
+		public int AuditNum { get; set; }
+
+		/// <summary>
+		/// 退回数量
+		/// </summary>
+		public int AuditBackNum { get; set; }
+
+		/// <summary>
+		/// 小计
+		/// </summary>
+		public int Total => AuditNum + AuditBackNum;
+	}
 }

+ 33 - 3
src/Hotline.Share/Dtos/Order/OrderVisitDto.cs

@@ -4,6 +4,7 @@ using Hotline.Share.Requests;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
+using System.ComponentModel.DataAnnotations;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -60,6 +61,27 @@ namespace Hotline.Share.Dtos.Order
         public bool? IsEffectiveAiVisit { get; set; }
     }
 
+    public class QueryOrderVisitSourceChannelDto
+    { 
+        /// <summary>
+        /// 开始时间
+        /// </summary>
+        [Required]
+        public DateTime StartTime { get; set; }
+
+        /// <summary>
+        /// 结束时间
+        /// </summary>
+        public DateTime? EndTime { get; set; }
+
+        /// <summary>
+        /// 非时间段统计 EndTime 可以不传;0=按日统计, 1=按周统计, 2=按月统计, 3=按时间段统计;
+        /// </summary>
+        [Required]
+        [Range(0, 3, ErrorMessage = "统计时间类型必须在0-3之间")]
+        public EDateType DateType { get; set; }
+    }
+
     public record VisitJudgeQueryReq : PagedKeywordRequest
     {
         /// <summary>
@@ -418,6 +440,13 @@ namespace Hotline.Share.Dtos.Order
         NoVisit = 2,
     }
 
+    public class OrderVisitSourceChannelDto
+    {
+        public int Count { get; set; }
+
+        public string SourceChannel { get; set; }
+    }
+
     public class OrderVisitDto
     {
         public string Id { get; set; }
@@ -550,7 +579,7 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public List<OrderScreenDto> OrderScreens { get; set; }
 
-		public OrderDto Order => OrderVisit != null ? OrderVisit.Order : null;
+        public OrderDto Order => OrderVisit != null ? OrderVisit.Order : null;
 
         /// <summary>
         /// 语音评价(话务评价)
@@ -629,7 +658,8 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public string ScreenSendBackText => GetScreenSendBack() ? "是" : "否";
 
-        public bool GetScreenSendBack() {
+        public bool GetScreenSendBack()
+        {
             if (OrderScreens != null && OrderScreens.Any())
             {
                 if (OrderScreens.First().Status == EScreenStatus.SendBack && OrderScreens.First().SendBackApply)
@@ -641,7 +671,7 @@ namespace Hotline.Share.Dtos.Order
         }
         public bool ScreenSendBack => GetScreenSendBack();
 
-	}
+    }
 
     public class DistributionVisitRspDto
     {

+ 33 - 0
src/Hotline.Share/Enums/Order/EDateType.cs

@@ -0,0 +1,33 @@
+using System.ComponentModel;
+
+namespace Hotline.Share.Enums.Order;
+
+/// <summary>
+/// 时间类型
+/// </summary>
+public enum EDateType
+{
+    /// <summary>
+    /// 按日统计
+    /// </summary>
+    [Description("按日统计")]
+    Day = 0,
+
+    /// <summary>
+    /// 按周统计
+    /// </summary>
+    [Description("按周统计")]
+    Week = 1,
+
+    /// <summary>
+    /// 按月统计
+    /// </summary>
+    [Description("按月统计")]
+    Month = 2,
+
+    /// <summary>
+    /// 按时间段统计
+    /// </summary>
+    [Description("按时间段统计")]
+    TimeLimit = 3
+}

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

@@ -0,0 +1,40 @@
+namespace Hotline.Share.Requests
+{
+    public record OrderNoSigenRequestDto : PagedRequest
+    {
+        /// <summary>
+        /// 开始时间
+        /// </summary>
+        public DateTime StartTime { get; set; }
+
+        /// <summary>
+        /// 结束时间
+        /// </summary>
+        public DateTime EndTime { get; set; }
+
+        /// <summary>
+        /// 部门名称
+        /// </summary>
+        public string? OrgName { get; set; }
+
+        /// <summary>
+        /// 部门Code
+        /// </summary>
+        public string? OrgCode { get; set; }
+
+        /// <summary>
+        /// 是否省来源
+        /// </summary>
+        public bool? IsProvince { get; set; }
+
+        /// <summary>
+        /// 来电/信人身份0:全部 ,1:市民,2:企业
+        /// </summary>
+        public int? TypeId { get; set; }
+
+        /// <summary>
+        /// 数据来源 1:工单未签收,2:会签未签收
+        /// </summary>
+        public int? DataSoure { get; set; }
+    }
+}

+ 27 - 0
src/Hotline.Share/Requests/PagedKeywordRequest.cs

@@ -715,3 +715,30 @@ public record HotspotAndAcceptTypeStatisticsDetailReq : PagedRequest
 
 	public DateTime EndTime { get; set; }
 }
+
+public record OrderScreenApplyPagedRequest : PagedKeywordRequest
+{
+	/// <summary>
+	/// 提起人
+	/// </summary>
+	public string ApplyUserName { get; set; }
+
+	/// <summary>
+	/// 部门名称
+	/// </summary>
+	public string ApplyOrgName { get; set; }
+}
+
+public record OrderScreenAuditPagedRequest : PagedKeywordRequest
+{
+	/// <summary>
+	/// 审批人
+	/// </summary>
+	public string AuditUserName { get; set; }
+
+	/// <summary>
+	///  1 中心班长   2 中心领导
+	/// </summary>
+	public int? AuditType { get; set; }
+
+}

+ 0 - 2
src/Hotline/Orders/OrderVisit.cs

@@ -41,7 +41,6 @@ public class OrderVisit : CreationEntity
     [SugarColumn(IsNullable = true)]
     public EVisitType? VisitType { get; set; }
 
-
     /// <summary>
     /// 发布时间
     /// </summary>
@@ -77,7 +76,6 @@ public class OrderVisit : CreationEntity
     [SugarColumn(IsNullable = true)]
     public DateTime? VisitTime { get; set; }
 
-
     /// <summary>
     /// 回访明细
     /// </summary>

+ 8 - 10
src/Hotline/Orders/OrderVisitDetail.cs

@@ -7,7 +7,7 @@ using XF.Domain.Repository;
 
 namespace Hotline.Orders
 {
-    public class OrderVisitDetail: CreationEntity
+    public class OrderVisitDetail : CreationEntity
     {
 
         /// <summary>
@@ -15,25 +15,25 @@ namespace Hotline.Orders
         /// </summary>
         public string VisitId { get; set; }
 
-
         [Navigate(NavigateType.OneToOne, nameof(VisitId))]
         public OrderVisit OrderVisit { get; set; }
 
         /// <summary>
         /// 二次办理申请
         /// </summary>
-        [Navigate(NavigateType.OneToOne, nameof(Id),nameof(OrderSecondaryHandling.VisitDetailId))]
+        [Navigate(NavigateType.OneToOne, nameof(Id), nameof(OrderSecondaryHandling.VisitDetailId))]
         public OrderSecondaryHandling SecondaryHandling { get; set; }
 
         /// <summary>
         /// 甄别记录
         /// </summary>
-        [Navigate(NavigateType.OneToMany,  nameof(OrderScreen.VisitDetailId), nameof(Id))]
+        [Navigate(NavigateType.OneToMany, nameof(OrderScreen.VisitDetailId), nameof(Id))]
         public List<OrderScreen> OrderScreens { get; set; }
-		/// <summary>
-		/// 语音评价(话务评价)
-		/// </summary>
-		public EVoiceEvaluate? VoiceEvaluate { get; set; }
+
+        /// <summary>
+        /// 语音评价(话务评价)
+        /// </summary>
+        public EVoiceEvaluate? VoiceEvaluate { get; set; }
 
         /// <summary>
         /// 话务员评价(话务评价)
@@ -55,7 +55,6 @@ namespace Hotline.Orders
         /// </summary>
         public string? VolveConent { get; set; }
 
-
         /// <summary>
         /// 部门办件结果
         /// </summary>
@@ -95,6 +94,5 @@ namespace Hotline.Orders
         /// 回访对象类型 10:话务员 20:部门
         /// </summary>
         public EVisitTarget VisitTarget { get; set; }
-
     }
 }

+ 56 - 6
src/Hotline/Settings/SettingConstants.cs

@@ -354,12 +354,12 @@ namespace Hotline.Settings
         /// <summary>
         /// 派单员角色
         /// </summary>
-		public const string RolePaiDan = "RolePaiDan";
+        public const string RolePaiDan = "RolePaiDan";
 
         /// <summary>
         /// 坐席角色
         /// </summary>
-		public const string RoleZuoXi = "RoleZuoXi";
+        public const string RoleZuoXi = "RoleZuoXi";
         /// <summary>
         /// 呼入分机组号
         /// </summary>
@@ -400,14 +400,64 @@ namespace Hotline.Settings
         /// </summary>
         public const string IsOpenContingencyManagement = "IsOpenContingencyManagement";
 
-		/// <summary>
-		/// 系统版本地区
-		/// </summary>
-		public const string VersionsAreaCode = "VersionsAreaCode";
+        /// <summary>
+        /// 系统版本地区
+        /// </summary>
+        public const string VersionsAreaCode = "VersionsAreaCode";
 
         /// <summary>
         /// 系统管理员角色
         /// </summary>
         public const string SystemAdministrator = "SystemAdministrator";
+
+        /// <summary>
+        /// 呼叫中心socket地址
+        /// </summary>
+        public const string CallCenterSocketUrl = "CallCenterSocketUrl";
+
+        /// <summary>
+        /// 地图中心点坐标
+        /// </summary>
+        public const string LocationCenter = "LocationCenter";
+
+        /// <summary>
+        /// 备案号
+        /// </summary>
+        public const string RecordNumber = "RecordNumber";
+
+        /// <summary>
+        /// 城市名简写
+        /// </summary>
+        public const string CityAbbr = "CityAbbr";
+
+        /// <summary>
+        /// 运营商名称
+        /// </summary>
+        public const string Operate = "Operate";
+
+        /// <summary>
+        /// 技术支持
+        /// </summary>
+        public const string TechSupport = "TechSupport";
+
+        /// <summary>
+        /// 城市Code
+        /// </summary>
+        public const string CityCode = "CityCode";
+
+        /// <summary>
+        /// 城市名称
+        /// </summary>
+        public const string CityName = "CityName";
+
+        /// <summary>
+        /// 录音播放地址前缀
+        /// </summary>
+        public const string RecordPrefix = "RecordPrefix";
+
+        /// <summary>
+        /// 录音地址下载前缀
+        /// </summary>
+        public const string RecordDownLoadPrefix = "RecordDownLoadPrefix";
     }
 }

+ 47 - 0
src/Hotline/Tools/DateTimeExtensions.cs

@@ -0,0 +1,47 @@
+
+namespace Hotline.Tools;
+public static class DateTimeExtensions
+{
+    /// <summary>
+    /// 获取指定日期所在周的开始时间和结束时间
+    /// </summary>
+    /// <param name="date"></param>
+    /// <returns></returns>
+    public static (DateTime, DateTime) GetWeekStartAndEnd(this DateTime date)
+    {
+        int diff = date.DayOfWeek - DayOfWeek.Monday;
+        if (diff < 0)
+        {
+            diff += 7;
+        }
+
+        var weekStart = date.AddDays(-1 * diff).Date;
+        var weekEnd = weekStart.AddDays(7).AddTicks(-1);
+
+        return (weekStart, weekEnd);
+    }
+
+    /// <summary>
+    /// 获取指定日期所在天的开始时间和结束时间
+    /// </summary>
+    /// <param name="date"></param>
+    /// <returns></returns>
+    public static (DateTime, DateTime) GetDayStartAndEnd(this DateTime date)
+    {
+        var dayStart = date.Date; 
+        var dayEnd = dayStart.AddDays(1).AddTicks(-1); 
+        return (dayStart, dayEnd);
+    }
+
+    /// <summary>
+    /// 获取指定日期所在月的开始时间和结束时间
+    /// </summary>
+    /// <param name="date"></param>
+    /// <returns></returns>
+    public static (DateTime, DateTime) GetMonthStartAndEnd(this DateTime date)
+    {
+        var monthStart = new DateTime(date.Year, date.Month, 1);
+        var monthEnd = monthStart.AddMonths(1).AddTicks(-1);
+        return (monthStart, monthEnd);
+    }
+}