Browse Source

Merge branch 'dev' of http://110.188.24.182:10023/Fengwo/hotline into dev

田爽 10 months ago
parent
commit
e2340e134d

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

@@ -5,7 +5,6 @@ using Hotline.CallCenter.Calls;
 using Hotline.FlowEngine.Workflows;
 using Hotline.Orders;
 using Hotline.Repository.SqlSugar.Extensions;
-using Hotline.Repository.SqlSugar.Orders;
 using Hotline.Schedulings;
 using Hotline.Settings;
 using Hotline.Settings.Hotspots;
@@ -21,10 +20,9 @@ using Hotline.Share.Enums.Order;
 using Hotline.Share.Requests;
 using Hotline.Tools;
 using MapsterMapper;
-using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
+using MiniExcelLibs;
 using SqlSugar;
-using System.DirectoryServices.Protocols;
 using XF.Domain.Authentications;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
@@ -2049,10 +2047,10 @@ namespace Hotline.Api.Controllers.Bi
             data = await query.ToListAsync(HttpContext.RequestAborted);
             data.Add(new OrderReTransactVo
             {
-	            OrgName = "合计",
-	            Num = data.Select(s => s.Num).Sum(),
+                OrgName = "合计",
+                Num = data.Select(s => s.Num).Sum(),
             });
-			dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
             var dtos = data
              .Select(stu => _mapper.Map(stu, typeof(OrderReTransactVo), dynamicClass))
              .Cast<object>()
@@ -2693,28 +2691,28 @@ namespace Hotline.Api.Controllers.Bi
             var data = await _orderApplication.QueryOrderSourceHoursList(dto);
             var totalVo = new OrderSourceHeaderVo()
             {
-	            Time = "合计",
-	            Phone = data.Sum(x => x.Phone),
-	            Web = data.Sum(x => x.Web),
-	            Rests = data.Sum(x => x.Rests),
-	            Created = data.Sum(x => x.Created),
-	            WeChat = data.Sum(x => x.WeChat),
-	            App = data.Sum(x => x.App),
-	            WisdomYB = data.Sum(x => x.WisdomYB),
-	            Platform = data.Sum(x => x.Platform),
-	            Platform12328 = data.Sum(x => x.Platform12328),
-	            MayorAndNetizens = data.Sum(x => x.MayorAndNetizens),
-	            MediaYB = data.Sum(x => x.MediaYB),
-	            Platform12345 = data.Sum(x => x.Platform12345),
-	            Interaction = data.Sum(x => x.Interaction),
-	            ServiceYB = data.Sum(x => x.ServiceYB),
-	            CityTransfer = data.Sum(x => x.CityTransfer),
-	            Platform110 = data.Sum(x => x.Platform110),
-	            NoService = data.Sum(x => x.NoService),
-	            Iyb = data.Sum(x => x.Iyb)
+                Time = "合计",
+                Phone = data.Sum(x => x.Phone),
+                Web = data.Sum(x => x.Web),
+                Rests = data.Sum(x => x.Rests),
+                Created = data.Sum(x => x.Created),
+                WeChat = data.Sum(x => x.WeChat),
+                App = data.Sum(x => x.App),
+                WisdomYB = data.Sum(x => x.WisdomYB),
+                Platform = data.Sum(x => x.Platform),
+                Platform12328 = data.Sum(x => x.Platform12328),
+                MayorAndNetizens = data.Sum(x => x.MayorAndNetizens),
+                MediaYB = data.Sum(x => x.MediaYB),
+                Platform12345 = data.Sum(x => x.Platform12345),
+                Interaction = data.Sum(x => x.Interaction),
+                ServiceYB = data.Sum(x => x.ServiceYB),
+                CityTransfer = data.Sum(x => x.CityTransfer),
+                Platform110 = data.Sum(x => x.Platform110),
+                NoService = data.Sum(x => x.NoService),
+                Iyb = data.Sum(x => x.Iyb)
             };
             data.Add(totalVo);
-			return data;
+            return data;
         }
 
         /// <summary>
@@ -2725,36 +2723,40 @@ namespace Hotline.Api.Controllers.Bi
         [HttpGet("order_source_hours_report_columnar_list")]
         public async Task<Object> QueryOrderSourceHoursReportColumnarList([FromQuery] QueryOrderSourceRequest dto)
         {
-	        var data = await _orderApplication.QueryOrderSourceHoursList(dto);
-	        List<string> tiems = new List<string>();
-	        for (int i = 0; i < 24; i++)
-	        {
-		        var item = i.ToString("D2") + ":00 - " + i.ToString("D2") + ":59";
-		        tiems.Add(item);
-	        }
-			var dataList = (from t1 in tiems join t2 in data on t1 equals t2.Time into t1_t2 from item in t1_t2.DefaultIfEmpty()
-	            select new { 
-                    Time = t1,
-                    Phone = t1_t2.Select(x => x.Phone).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Phone).FirstOrDefault(),
-                    Web = t1_t2.Select(x => x.Web).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Web).FirstOrDefault(),
-					Rests = t1_t2.Select(x => x.Rests).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Rests).FirstOrDefault(),
-					Created = t1_t2.Select(x => x.Created).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Created).FirstOrDefault(),
-					WeChat = t1_t2.Select(x => x.WeChat).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.WeChat).FirstOrDefault(),
-					App = t1_t2.Select(x => x.App).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.App).FirstOrDefault(),
-					WisdomYB = t1_t2.Select(x => x.WisdomYB).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.WisdomYB).FirstOrDefault(),
-					Platform = t1_t2.Select(x => x.Platform).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Platform).FirstOrDefault(),
-					Platform12328 = t1_t2.Select(x => x.Platform12328).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Platform12328).FirstOrDefault(),
-					MayorAndNetizens = t1_t2.Select(x => x.MayorAndNetizens).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.MayorAndNetizens).FirstOrDefault(),
-					MediaYB = t1_t2.Select(x => x.MediaYB).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.MediaYB).FirstOrDefault(),
-					Platform12345 = t1_t2.Select(x => x.Platform12345).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Platform12345).FirstOrDefault(),
-					Interaction = t1_t2.Select(x => x.Interaction).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Interaction).FirstOrDefault(),
-					ServiceYB = t1_t2.Select(x => x.ServiceYB).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.ServiceYB).FirstOrDefault(),
-					CityTransfer = t1_t2.Select(x => x.CityTransfer).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.CityTransfer).FirstOrDefault(),
-					Platform110 = t1_t2.Select(x => x.Platform110).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Platform110).FirstOrDefault(),
-					NoService = t1_t2.Select(x => x.NoService).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.NoService).FirstOrDefault(),
-					Iyb = t1_t2.Select(x => x.Iyb).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Iyb).FirstOrDefault(),
-				}).ToList();
-            var res = new { 
+            var data = await _orderApplication.QueryOrderSourceHoursList(dto);
+            List<string> tiems = new List<string>();
+            for (int i = 0; i < 24; i++)
+            {
+                var item = i.ToString("D2") + ":00 - " + i.ToString("D2") + ":59";
+                tiems.Add(item);
+            }
+            var dataList = (from t1 in tiems
+                            join t2 in data on t1 equals t2.Time into t1_t2
+                            from item in t1_t2.DefaultIfEmpty()
+                            select new
+                            {
+                                Time = t1,
+                                Phone = t1_t2.Select(x => x.Phone).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Phone).FirstOrDefault(),
+                                Web = t1_t2.Select(x => x.Web).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Web).FirstOrDefault(),
+                                Rests = t1_t2.Select(x => x.Rests).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Rests).FirstOrDefault(),
+                                Created = t1_t2.Select(x => x.Created).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Created).FirstOrDefault(),
+                                WeChat = t1_t2.Select(x => x.WeChat).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.WeChat).FirstOrDefault(),
+                                App = t1_t2.Select(x => x.App).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.App).FirstOrDefault(),
+                                WisdomYB = t1_t2.Select(x => x.WisdomYB).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.WisdomYB).FirstOrDefault(),
+                                Platform = t1_t2.Select(x => x.Platform).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Platform).FirstOrDefault(),
+                                Platform12328 = t1_t2.Select(x => x.Platform12328).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Platform12328).FirstOrDefault(),
+                                MayorAndNetizens = t1_t2.Select(x => x.MayorAndNetizens).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.MayorAndNetizens).FirstOrDefault(),
+                                MediaYB = t1_t2.Select(x => x.MediaYB).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.MediaYB).FirstOrDefault(),
+                                Platform12345 = t1_t2.Select(x => x.Platform12345).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Platform12345).FirstOrDefault(),
+                                Interaction = t1_t2.Select(x => x.Interaction).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Interaction).FirstOrDefault(),
+                                ServiceYB = t1_t2.Select(x => x.ServiceYB).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.ServiceYB).FirstOrDefault(),
+                                CityTransfer = t1_t2.Select(x => x.CityTransfer).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.CityTransfer).FirstOrDefault(),
+                                Platform110 = t1_t2.Select(x => x.Platform110).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Platform110).FirstOrDefault(),
+                                NoService = t1_t2.Select(x => x.NoService).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.NoService).FirstOrDefault(),
+                                Iyb = t1_t2.Select(x => x.Iyb).FirstOrDefault() == null ? 0 : t1_t2.Select(x => x.Iyb).FirstOrDefault(),
+                            }).ToList();
+            var res = new
+            {
                 Phone = new { Key = "电话", data = dataList.Select(x => x.Phone) },
                 Web = new { Key = "因特网", data = dataList.Select(x => x.Web) },
                 Rests = new { Key = "其他", data = dataList.Select(x => x.Rests) },
@@ -2773,16 +2775,16 @@ namespace Hotline.Api.Controllers.Bi
                 Platform110 = new { Key = "宜宾110平台", data = dataList.Select(x => x.Platform110) },
                 NoService = new { Key = "办不成事反映窗口", data = dataList.Select(x => x.NoService) },
                 Iyb = new { Key = "I宜宾", data = dataList.Select(x => x.Iyb) }
-			};
-			return res;
+            };
+            return res;
         }
 
-		/// <summary>
-		/// 信件来源分时统计表头
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpGet("order_source_hours_report_header")]
+        /// <summary>
+        /// 信件来源分时统计表头
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("order_source_hours_report_header")]
         public async Task<Object> QueryOrderSourceHoursReportHeader()
         {
             List<Kv> header = new List<Kv>
@@ -2803,7 +2805,7 @@ namespace Hotline.Api.Controllers.Bi
                 new Kv { Key = "宜办事", Value = "ServiceYB" },
                 new Kv { Key = "市州互转", Value = "CityTransfer" },
                 new Kv { Key = "宜宾110平台", Value = "Platform110" },
-				new Kv { Key = "办不成事反映窗口", Value = "NoService" },
+                new Kv { Key = "办不成事反映窗口", Value = "NoService" },
                 new Kv { Key = "I宜宾", Value = "Iyb" }
             };
             List<string> tiems = new List<string>();
@@ -2811,8 +2813,8 @@ namespace Hotline.Api.Controllers.Bi
             {
                 var item = i.ToString("D2") + ":00 - " + i.ToString("D2") + ":59";
                 tiems.Add(item);
-			}
-            return new { Header = header,Tiems = tiems };
+            }
+            return new { Header = header, Tiems = tiems };
         }
 
         /// <summary>
@@ -2825,28 +2827,28 @@ namespace Hotline.Api.Controllers.Bi
             var data = await _orderApplication.QueryOrderSourceHoursList(dto.QueryDto);
             var totalVo = new OrderSourceHeaderVo()
             {
-	            Time = "合计",
-	            Phone = data.Sum(x => x.Phone),
-	            Web = data.Sum(x => x.Web),
-	            Rests = data.Sum(x => x.Rests),
-	            Created = data.Sum(x => x.Created),
-	            WeChat = data.Sum(x => x.WeChat),
-	            App = data.Sum(x => x.App),
-	            WisdomYB = data.Sum(x => x.WisdomYB),
-	            Platform = data.Sum(x => x.Platform),
-	            Platform12328 = data.Sum(x => x.Platform12328),
-	            MayorAndNetizens = data.Sum(x => x.MayorAndNetizens),
-	            MediaYB = data.Sum(x => x.MediaYB),
-	            Platform12345 = data.Sum(x => x.Platform12345),
-	            Interaction = data.Sum(x => x.Interaction),
-	            ServiceYB = data.Sum(x => x.ServiceYB),
-	            CityTransfer = data.Sum(x => x.CityTransfer),
-	            Platform110 = data.Sum(x => x.Platform110),
-	            NoService = data.Sum(x => x.NoService),
-	            Iyb = data.Sum(x => x.Iyb)
+                Time = "合计",
+                Phone = data.Sum(x => x.Phone),
+                Web = data.Sum(x => x.Web),
+                Rests = data.Sum(x => x.Rests),
+                Created = data.Sum(x => x.Created),
+                WeChat = data.Sum(x => x.WeChat),
+                App = data.Sum(x => x.App),
+                WisdomYB = data.Sum(x => x.WisdomYB),
+                Platform = data.Sum(x => x.Platform),
+                Platform12328 = data.Sum(x => x.Platform12328),
+                MayorAndNetizens = data.Sum(x => x.MayorAndNetizens),
+                MediaYB = data.Sum(x => x.MediaYB),
+                Platform12345 = data.Sum(x => x.Platform12345),
+                Interaction = data.Sum(x => x.Interaction),
+                ServiceYB = data.Sum(x => x.ServiceYB),
+                CityTransfer = data.Sum(x => x.CityTransfer),
+                Platform110 = data.Sum(x => x.Platform110),
+                NoService = data.Sum(x => x.NoService),
+                Iyb = data.Sum(x => x.Iyb)
             };
             data.Add(totalVo);
-			dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
             var dtos = data
                 .Select(stu => _mapper.Map(stu, typeof(OrderSourceHeaderVo), dynamicClass))
                 .Cast<object>()
@@ -2876,6 +2878,21 @@ namespace Hotline.Api.Controllers.Bi
             return new { Item = item, TitleData = titleData };
         }
 
+        /// <summary>
+        /// 区域分时统计-导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("order_area_time_export")]
+        public async Task<FileStreamResult> OrderAreaTimeExport([FromBody] AreaTimePagedKeywordRequest dto)
+        {
+            var dataTable = await _orderRepository.OrderAreaTimeExport(dto.StartTime, dto.EndTime, dto.AddColumnName);
+
+            var stream = new MemoryStream();
+            stream.SaveAs(dataTable);
+            stream.Seek(0, SeekOrigin.Begin);
+            return ExcelStreamResult(stream, "区域分时统计数据");
+        }
 
         /// <summary>
         /// 
@@ -3077,5 +3094,5 @@ namespace Hotline.Api.Controllers.Bi
 
         }
     }
-    
+
 }

+ 3 - 3
src/Hotline.Api/Controllers/TestController.cs

@@ -205,7 +205,7 @@ public class TestController : BaseController
     public async Task<object> Test111(DateTime StartTime, DateTime EndTime)
     {
 
-        var list11 =await  _orderRepository.Queryable()
+        var list11 = await _orderRepository.Queryable()
                  .Where(p => p.CreationTime >= StartTime && p.CreationTime <= EndTime)
                  .Select(p => new
                  {
@@ -220,11 +220,11 @@ public class TestController : BaseController
                  {
                      AreaCode = a.AreaName,
                      Hour = p.Hour,
-                     count = SqlFunc.AggregateSum(SqlFunc.IIF(p.AreaCode!= null, 1, 0) )
+                     count = SqlFunc.AggregateSum(SqlFunc.IIF(p.AreaCode != null, 1, 0))
                  })//.ToListAsync();
                 .ToPivotTableAsync(p => p.AreaCode, p => p.Hour, p => p.Sum(x => x.count));
 
-        var list=await _orderRepository.OrderAreaTime(StartTime, EndTime);    
+        var list = await _orderRepository.OrderAreaTimeExport(StartTime, EndTime, new List<string>());
         return list;
     }
 

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

@@ -99,7 +99,7 @@ namespace Hotline.Repository.SqlSugar.CallCenter
                     EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.Duration >= effectiveTimes, 1, 0)),//有效接通
                     ConnectByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.Duration > 0 && o.Duration <= connectByeTimes, 1, 0)), //接通秒挂
                     NoConnectByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.Duration == 0 && o.RingTimes <= noConnectByeTimes && o.RingTimes>0, 1, 0)), //未接通秒挂
-                    QueueByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.QueueTims > 0 && o.RingTimes == 0, 1, 0)), //队列挂断
+                    QueueByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.QueueTims > 0 && o.RingTimes == 0 && o.OnState == EOnState.NoOn, 1, 0)), //队列挂断
                     IvrByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.BeginIvrTime.HasValue && !o.BeginQueueTime.HasValue && !o.BeginRingTime.HasValue && o.OnState == EOnState.NoOn, 1, 0)), //IVR挂断
                 })
                 .MergeTable()

+ 2 - 2
src/Hotline.Repository.SqlSugar/Extensions/SqlSugarStartupExtensions.cs

@@ -207,8 +207,8 @@ namespace Hotline.Repository.SqlSugar.Extensions
             /***写AOP等方法***/
             db.Aop.OnLogExecuting = (sql, pars) =>
             {
-                //Log.Information("Sql: {0}", sql);
-                //Log.Information("SqlParameters: {0}", string.Join(',', pars.Select(d => d.Value)));
+                Log.Information("Sql: {0}", sql);
+                Log.Information("SqlParameters: {0}", string.Join(',', pars.Select(d => d.Value)));
             };
             db.Aop.OnError = (exp) =>//SQL报错
             {

+ 103 - 4
src/Hotline.Repository.SqlSugar/Orders/OrderRepository.cs

@@ -8,6 +8,7 @@ using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Requests;
 using SqlSugar;
+using System.Data;
 using System.Reflection;
 using XF.Domain.Dependency;
 
@@ -183,28 +184,126 @@ namespace Hotline.Repository.SqlSugar.Orders
             var listOrg = Db.Queryable<SystemArea>()
               .LeftJoin(listOrder, (s, p) => s.Id == p.AreaCode)
               .Where((s, p) => s.Id.Length == 6 && s.Id != "510000")
-              .GroupBy((s, p) => s.Id)
+              .GroupBy((s, p) => s.Id).GroupBy((s, p) => s.AreaName)
               .GroupBy((s, p) => p.Hour)
               .Select((s, p) => new
               {
                   count = SqlFunc.AggregateSum(SqlFunc.IIF(p.AreaCode != null && p.AreaCode != "", 1, 0)),
                   AreaCode = s.Id,
-                  Hour = SqlFunc.IIF(p.Hour == null || p.Hour == "", "0", p.Hour)
+                  Hour = SqlFunc.IIF(p.Hour == null || p.Hour == "", "0", p.Hour),
+                  AreaName = s.AreaName
               })
               .MergeTable();
 
-            return await listHour.LeftJoin(listOrg, (x, p) => x.ColumnName.ToString() == p.Hour)
+            var list = await listHour.LeftJoin(listOrg, (x, p) => x.ColumnName.ToString() == p.Hour)
                 .OrderBy(x => x.ColumnName)
                .Select((x, p) => new
                {
-                   Hour = x.ColumnName.ToString()+":00 - "+ x.ColumnName.ToString()+":59",
+                   Hour = x.ColumnName.ToString() + ":00 - " + x.ColumnName.ToString() + ":59",
                    p.AreaCode,
                    p.count
                })
                 .ToPivotListAsync(p => p.AreaCode, p => p.Hour, p => p.Sum(x => x.count));
+            return list;
 
         }
 
+        /// <summary>
+        /// 区域分时统计
+        /// </summary>
+        /// <param name="StartTime"></param>
+        /// <param name="EndTime"></param>
+        /// <param name="RemoveColumnName"></param>
+        /// <returns></returns>
+        public async Task<DataTable> OrderAreaTimeExport(DateTime? StartTime, DateTime? EndTime, List<string> AddColumnName)
+        {
+            List<int> dts = new();
+            for (int i = 0; i < 24; i++)
+            {
+                dts.Add(i);
+            }
+
+            var listHour = Db.Reportable(dts).ToQueryable<int>();
+            var listOrder = Db.Queryable<Order>()
+                 .Where(p => p.CreationTime >= StartTime && p.CreationTime <= EndTime)
+                 .Select(p => new
+                 {
+                     AreaCode = p.AreaCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")),
+                     Hour = p.CreationTime.Hour.ToString()
+                 })
+               .MergeTable();
+
+            var listOrg = Db.Queryable<SystemArea>()
+              .LeftJoin(listOrder, (s, p) => s.Id == p.AreaCode)
+              .Where((s, p) => s.Id.Length == 6 && s.Id != "510000")
+              .GroupBy((s, p) => s.Id).GroupBy((s, p) => s.AreaName)
+              .GroupBy((s, p) => p.Hour)
+              .Select((s, p) => new
+              {
+                  count = SqlFunc.AggregateSum(SqlFunc.IIF(p.AreaCode != null && p.AreaCode != "", 1, 0)),
+                  AreaCode = s.Id,
+                  Hour = SqlFunc.IIF(p.Hour == null || p.Hour == "", "0", p.Hour),
+                  AreaName = s.AreaName
+              })
+              .MergeTable();
+
+            var dt = await listHour.LeftJoin(listOrg, (x, p) => x.ColumnName.ToString() == p.Hour)
+               .OrderBy(x => x.ColumnName)
+              .Select((x, p) => new
+              {
+                  Hour = x.ColumnName.ToString() + ":00 - " + x.ColumnName.ToString() + ":59",
+                  p.AreaName,
+                  p.count
+              })
+               .ToPivotTableAsync(p => p.AreaName, p => p.Hour, p => p.Sum(x => x.count));
+
+            //修改列名
+            dt.Columns["Hour"].ColumnName = "时间段";
+            dt.Columns.Remove("Column1");
+
+            //增加小计
+            DataColumn totalColumn = new DataColumn("小计", typeof(decimal));
+            dt.Columns.Add(totalColumn);
+            for (int i = 0; i < dt.Rows.Count; i++)
+            {
+                int sumcount = 0;
+                for (int j = 1; j < dt.Columns.Count - 1; j++)
+                {
+                    sumcount += Convert.ToInt32(dt.Rows[i][j].ToString());
+                }
+                dt.Rows[i][dt.Columns.Count - 1] = sumcount;
+            }
+
+            //增加合计
+            DataRow totalRow = dt.NewRow();
+            totalRow["时间段"] = "合计";
+            for (int i = 1; i < dt.Columns.Count; i++)
+            {
+                int sumcount = 0;
+                for (int j = 0; j < dt.Rows.Count; j++)
+                {
+                    sumcount += Convert.ToInt32(dt.Rows[j][i].ToString());
+                }
+                totalRow[i] = sumcount;
+            }
+            dt.Rows.Add(totalRow);
+
+            //移除列
+            if (AddColumnName.Any())
+            {
+                for (int i = 0; i < dt.Columns.Count; i++)
+                {
+                    var name = dt.Columns[i].ColumnName;
+                    if (!AddColumnName.Contains(name))
+                    {
+                        dt.Columns.Remove(name);
+                        i = 0;
+                    }
+                }
+            }
+            return dt;
+        }
+
         public ISugarQueryable<SelectOrderId> OrderListUnionAll(ISugarQueryable<SelectOrderId> t1, ISugarQueryable<SelectOrderId> t2)
         {
             return Db.UnionAll(t1, t2).Select(it => new SelectOrderId { Id = it.Id }).MergeTable();

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

@@ -270,3 +270,8 @@ public record QueryOrderSourceDetailRequest : QueryOrderSourceRequest
 	/// </summary>
 	public string? SourceChannel { get; set; }
 }
+
+public record AreaTimePagedKeywordRequest: PagedKeywordRequest
+{
+	public List<string> AddColumnName { get; set; }
+}

+ 10 - 0
src/Hotline/Orders/IOrderRepository.cs

@@ -1,5 +1,6 @@
 using Hotline.Share.Requests;
 using SqlSugar;
+using System.Data;
 using XF.Domain.Repository;
 
 namespace Hotline.Orders
@@ -32,6 +33,15 @@ namespace Hotline.Orders
         /// <returns></returns>
         Task<object> OrderAreaTime(DateTime? StartTime, DateTime? EndTime);
 
+        /// <summary>
+        /// 区域分时统计导出
+        /// </summary>
+        /// <param name="StartTime"></param>
+        /// <param name="EndTime"></param>
+        /// <param name="AddColumnName"></param>
+        /// <returns></returns>
+        Task<DataTable> OrderAreaTimeExport(DateTime? StartTime, DateTime? EndTime, List<string> AddColumnName);
+
     }
 
     public interface IOrderScreenRepository : IRepositoryWorkflow<OrderScreen>