瀏覽代碼

Merge branch 'dev' of http://git.12345lm.cn/Fengwo/hotline into dev

tangjiang 10 月之前
父節點
當前提交
24de2b8967

+ 66 - 193
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -10,6 +10,7 @@ using Hotline.Settings;
 using Hotline.Settings.Hotspots;
 using Hotline.Settings.TimeLimits;
 using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.Ai;
 using Hotline.Share.Dtos.Bi;
 using Hotline.Share.Dtos.Bigscreen;
 using Hotline.Share.Dtos.CallCenter;
@@ -23,6 +24,7 @@ using MapsterMapper;
 using Microsoft.AspNetCore.Mvc;
 using MiniExcelLibs;
 using SqlSugar;
+using System.Data;
 using XF.Domain.Authentications;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
@@ -1320,7 +1322,7 @@ namespace Hotline.Api.Controllers.Bi
               {
                   CountNum = SqlFunc.AggregateCount(it.OrgLevelOneCode),
 
-                  OrgName = it.OrgLevelOneCode == "001" ? "热线中心" : o.Name
+                  OrgName = it.OrgLevelOneCode == "001" ? "市民热线服务中心" : o.Name
               }).ToListAsync();
 
             centerReportStatisticsDto.OrgStatisticsCityAll = new OrgStatisticsAll
@@ -1340,7 +1342,7 @@ namespace Hotline.Api.Controllers.Bi
              .Select((it, o) => new OrgStatistics
              {
                  CountNum = SqlFunc.AggregateCount(it.OrgLevelOneCode),
-                 OrgName = it.OrgLevelOneCode == "001" ? "热线中心" : o.Name
+                 OrgName = it.OrgLevelOneCode == "001" ? "市民热线服务中心" : o.Name
              }).ToListAsync();
 
             centerReportStatisticsDto.OrgStatisticsAreaAll = new OrgStatisticsAll
@@ -2621,28 +2623,31 @@ namespace Hotline.Api.Controllers.Bi
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpGet("order_source_report_list")]
-        public async Task<List<OrderSourceHeaderVo>> QueryOrderSourceReportList([FromQuery] QueryOrderSourceRequest dto)
+        public async Task<Object> QueryOrderSourceReportList([FromQuery] QueryOrderSourceRequest dto)
         {
-            var data = await _orderApplication.QueryOrderSourceList(dto);
-            return data;
-            ;
+            var item = await _orderRepository.OrderSource(dto);
+
+            var titleData = await _systemDicDataRepository.Queryable()
+                .Where(p => p.DicTypeCode == "SourceChannel")
+                .Select(p => new
+                {
+                    Key = p.DicDataValue,
+                    Value = p.DicDataName
+                }).ToListAsync();
+
+            return new { Item = item, TitleData = titleData };
         }
         /// <summary>
         /// 信件来源统计导出
         /// </summary>
         /// <returns></returns>
         [HttpPost("order_source_list/_export")]
-        public async Task<FileStreamResult> QueryOrderSourceReportList([FromBody] ExportExcelDto<QueryOrderSourceRequest> dto)
+        public async Task<FileStreamResult> QueryOrderSourceListExport([FromBody] QueryOrderSourceRequest dto)
         {
-            var data = await _orderApplication.QueryOrderSourceList(dto.QueryDto);
-            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
-            var dtos = data
-                .Select(stu => _mapper.Map(stu, typeof(OrderSourceHeaderVo), dynamicClass))
-                .Cast<object>()
-                .ToList();
-            var stream = ExcelHelper.CreateStream(dtos);
-            return ExcelStreamResult(stream, "信件来源统计列表数据");
-        }
+            var dataTable = await _orderRepository.OrderSourceExport(dto);
+            var stream = ExcelHelper.CreateStream(dataTable);
+            return ExcelStreamResult(stream, "信件来源统计数据");
+		}
 
         /// <summary>
         /// 信件来源统计明细
@@ -2683,183 +2688,6 @@ namespace Hotline.Api.Controllers.Bi
             return ExcelStreamResult(stream, "信件来源统计明细数据");
         }
 
-        /// <summary>
-        /// 信件来源分时统计列表
-        /// </summary>
-        /// <param name="dto"></param>
-        /// <returns></returns>
-        [HttpGet("order_source_hours_report_list")]
-        public async Task<List<OrderSourceHeaderVo>> QueryOrderSourceHoursReportList([FromQuery] QueryOrderSourceRequest dto)
-        {
-            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)
-            };
-            data.Add(totalVo);
-            return data;
-        }
-
-        /// <summary>
-        /// 信件来源分时统计柱状列表
-        /// </summary>
-        /// <param name="dto"></param>
-        /// <returns></returns>
-        [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
-            {
-                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) },
-                Created = new { Key = "自建", data = dataList.Select(x => x.Created) },
-                WeChat = new { Key = "微信", data = dataList.Select(x => x.WeChat) },
-                App = new { Key = "APP", data = dataList.Select(x => x.App) },
-                WisdomYB = new { Key = "智慧宜宾", data = dataList.Select(x => x.WisdomYB) },
-                Platform = new { Key = "综治平台", data = dataList.Select(x => x.Platform) },
-                Platform12328 = new { Key = "省12328平台", data = dataList.Select(x => x.Platform12328) },
-                MayorAndNetizens = new { Key = "市州与网民", data = dataList.Select(x => x.MayorAndNetizens) },
-                MediaYB = new { Key = "宜宾融媒体", data = dataList.Select(x => x.MediaYB) },
-                Platform12345 = new { Key = "省12345平台", data = dataList.Select(x => x.Platform12345) },
-                Interaction = new { Key = "省政民互动", data = dataList.Select(x => x.Interaction) },
-                ServiceYB = new { Key = "宜办事", data = dataList.Select(x => x.ServiceYB) },
-                CityTransfer = new { Key = "市州互转", data = dataList.Select(x => x.CityTransfer) },
-                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;
-        }
-
-        /// <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>
-            {
-                new Kv { Key = "电话", Value = "Phone" },
-                new Kv { Key = "因特网", Value = "Web" },
-                new Kv { Key = "其他", Value = "Rests" },
-                new Kv { Key = "自建", Value = "Created" },
-                new Kv { Key = "微信", Value = "WeChat" },
-                new Kv { Key = "APP", Value = "App" },
-                new Kv { Key = "智慧宜宾", Value = "WisdomYB" },
-                new Kv { Key = "综治平台", Value = "Platform" },
-                new Kv { Key = "省12328平台", Value = "Platform12328" },
-                new Kv { Key = "市州与网民", Value = "MayorAndNetizens" },
-                new Kv { Key = "宜宾融媒体", Value = "MediaYB" },
-                new Kv { Key = "省12345平台", Value = "Platform12345" },
-                new Kv { Key = "省政民互动", Value = "Interaction" },
-                new Kv { Key = "宜办事", Value = "ServiceYB" },
-                new Kv { Key = "市州互转", Value = "CityTransfer" },
-                new Kv { Key = "宜宾110平台", Value = "Platform110" },
-                new Kv { Key = "办不成事反映窗口", Value = "NoService" },
-                new Kv { Key = "I宜宾", Value = "Iyb" }
-            };
-            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);
-            }
-            return new { Header = header, Tiems = tiems };
-        }
-
-        /// <summary>
-        /// 信件来源分时统计导出
-        /// </summary>
-        /// <returns></returns>
-        [HttpPost("order_source_hours_list/_export")]
-        public async Task<FileStreamResult> QueryOrderSourceHoursReportList([FromBody] ExportExcelDto<QueryOrderSourceRequest> dto)
-        {
-            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)
-            };
-            data.Add(totalVo);
-            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
-            var dtos = data
-                .Select(stu => _mapper.Map(stu, typeof(OrderSourceHeaderVo), dynamicClass))
-                .Cast<object>()
-                .ToList();
-            var stream = ExcelHelper.CreateStream(dtos);
-            return ExcelStreamResult(stream, "信件来源分时统计列表数据");
-        }
-
         /// <summary>
         /// 区域分时统计
         /// </summary>
@@ -2995,6 +2823,51 @@ namespace Hotline.Api.Controllers.Bi
             var stream = ExcelHelper.CreateStream(dataTable);
             return ExcelStreamResult(stream, "信件来源分时统计数据");
         }
+
+        /// <summary>
+        /// 部门满意度明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("org-visitdetail-list")]
+        public async Task<PagedDto<OrgVisitDetailListResp>> OrgVisitDetailList([FromQuery]OrgVisitDetailListReq dto)
+        {
+            var query = _orderRepository.OrgVisitDetailList(dto);
+            var (total,items) =await query.ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
+
+            return new PagedDto<OrgVisitDetailListResp>(total, _mapper.Map<IReadOnlyList<OrgVisitDetailListResp>>(items));
+        }
+
+        /// <summary>
+        /// 部门满意度明细导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("org-visitdetail-list-export")]
+        public async Task<FileStreamResult> OrgVisitDetailListExport([FromBody] ExportExcelDto<OrgVisitDetailListReq> dto)
+        {
+            var query = _orderRepository.OrgVisitDetailList(dto.QueryDto);
+
+            List<OrderVisitDetail> 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<OrgVisitDetailListResp>>(orders);
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+            var dtos = ordersDtos
+                .Select(stu => _mapper.Map(stu, typeof(OrgVisitDetailListResp), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+            return ExcelStreamResult(stream, "部门满意度明细");
+        }
     }
 
 }

+ 4 - 4
src/Hotline.Api/Controllers/OrderController.cs

@@ -1600,7 +1600,7 @@ public class OrderController : BaseController
             .WhereIF(!string.IsNullOrEmpty(dto.OrgProcessingResults), x => SqlFunc.JsonField(x.OrgProcessingResults, "Key") == dto.OrgProcessingResults)
             .WhereIF(!string.IsNullOrEmpty(dto.OrgHandledAttitude), x => SqlFunc.JsonListObjectAny(x.OrgHandledAttitude, "Key", dto.OrgHandledAttitude))
             .WhereIF(!string.IsNullOrEmpty(dto.OrgNoSatisfiedReason), x => SqlFunc.JsonField(x.OrgNoSatisfiedReason, "Key") == dto.OrgNoSatisfiedReason)
-            .Where((x, s) => x.OrderVisit.VisitState != EVisitState.None && x.OrderVisit.IsCanHandle);
+            .Where((x, s) => x.OrderVisit.VisitState == EVisitState.Visited && x.OrderVisit.IsCanHandle);
         if (_sessionContext.OrgId != null && !_sessionContext.OrgIsCenter)
         {
             query.WhereIF(!string.IsNullOrEmpty(dto.Keyword),
@@ -1644,7 +1644,7 @@ public class OrderController : BaseController
         var view = dto.source == 1;
         var handler = dto.source == 1 && dto.Status is EScreenStatus.Apply;
 
-        var query = _orderScreenRepository.Queryable(canView: view, hasHandled: handler)
+        var query = _orderScreenRepository.Queryable(hasHandled: handler)
             .Includes(d => d.Order)
             .Includes(d => d.VisitDetail)
             .Includes(d => d.Visit, v => v.Order)
@@ -2600,7 +2600,7 @@ public class OrderController : BaseController
         }
 
         //内容分词
-        await _orderApplication.OrderParticiple(dto.Content, order.Id, HttpContext.RequestAborted);
+        await _orderApplication.OrderParticiple(dto.Content, order.Id,order.CreationTime, HttpContext.RequestAborted);
         //敏感分词
         await _orderApplication.OrderSensitiveParticiple(dto.Content, order.Id, HttpContext.RequestAborted);
         //sms
@@ -2725,7 +2725,7 @@ public class OrderController : BaseController
             throw UserFriendlyException.SameMessage("工单已发起流程,不可编辑");
 
         if (order.Content != dto.Content)
-            await _orderApplication.OrderParticiple(dto.Content, dto.Id, HttpContext.RequestAborted);
+            await _orderApplication.OrderParticiple(dto.Content, dto.Id, order.CreationTime, HttpContext.RequestAborted);
         if (dto.RepeatableEventDetails?.Any() ?? false)
         {
             var reAdds = dto.RepeatableEventDetails.Where(x => string.IsNullOrEmpty(x.OrderId) && !x.IsDeleted)

+ 2 - 2
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -992,7 +992,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         return new NextStepOption
         {
             Key = orgLevel.ToString(),
-            Value = orgLevel == 0 ? "热线中心" : $"{orgLevel.ToChinese()}级部门",
+            Value = orgLevel == 0 ? "市民热线服务中心" : $"{orgLevel.ToChinese()}级部门",
         };
     }
 
@@ -1122,7 +1122,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         return new NextStepOption
         {
             Key = orgLevel.ToString(),
-            Value = orgLevel == 0 ? "热线中心" : $"{orgLevel.ToChinese()}级部门",
+            Value = orgLevel == 0 ? "市民热线服务中心" : $"{orgLevel.ToChinese()}级部门",
             FlowDirection = flowDirection,
             StepType = stepType,
             BusinessType = businessType,

+ 36 - 0
src/Hotline.Application/Mappers/OrderMapperConfigs.cs

@@ -40,6 +40,42 @@ public class OrderMapperConfigs : IRegister
                 d.IsSuccessText = s.IsSuccess == true ? "是" : "否";
             });
 
+        config.ForType<OrderVisitDetail, OrgVisitDetailListResp>()
+            //.IgnoreIf((s, d) => s.OrderVisit == null, d => d.VisitId)
+            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.Id)
+            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.No)
+            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.ReTransactNum)
+            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.HotspotSpliceName)
+            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.OrgLevelOneName)
+            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.ActualHandleOrgName)
+            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.Title)
+            .IgnoreIf((s, d) => s.OrderVisit.Employee == null, d => d.VisitUser)
+            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.Content)
+            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.FileOpinion)
+            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.FiledTime)
+            .Map(d => d.VisitId, s => s.OrderVisit.Id)
+            .Map(d => d.Id, s => s.OrderVisit.Order.Id)
+            .Map(d => d.No, s => s.OrderVisit.Order.No)
+            .Map(d => d.ReTransactNum, s => s.OrderVisit.Order.ReTransactNum)
+            .Map(d => d.HotspotSpliceName, s => s.OrderVisit.Order.HotspotSpliceName)
+            .Map(d => d.OrgLevelOneName, s => s.OrderVisit.Order.OrgLevelOneName)
+            .Map(d => d.ActualHandleOrgName, s => s.OrderVisit.Order.ActualHandleOrgName)
+            .Map(d => d.Title, s => s.OrderVisit.Order.Title)
+            .Map(d => d.VisitUser, s => s.OrderVisit.Employee.Name)
+            .Map(d => d.VisitType, s => s.OrderVisit.VisitType)
+            .Map(d => d.VisitTime, s => s.OrderVisit.VisitTime)
+            .Map(d => d.Content, s => s.OrderVisit.Order.Content)
+            .Map(d => d.FileOpinion, s => s.OrderVisit.Order.FileOpinion)
+            .Map(d => d.FiledTime, s => s.OrderVisit.Order.FiledTime)
+            .AfterMapping((s, d) =>
+            {
+                d.OrderScreenStatus = s.OrderVisit.Order.OrderScreens.OrderByDescending(q=>q.CreationTime).FirstOrDefault()?.Status;
+                d.OrgProcessingResults = s.OrgProcessingResults.Value;
+            });
+
+            
+
+
 
 
         config.ForType<AddOrderDto, Order>()

+ 1 - 15
src/Hotline.Application/Orders/IOrderApplication.cs

@@ -44,7 +44,7 @@ namespace Hotline.Application.Orders
 		//Task<PagedDto<WorkflowOrderDto>> GetToExpireNodeAsync(AboutToExpireListDto dto, CancellationToken cancellationToken);
 		ISugarQueryable<Order> GetAboutToExpireAsync(AboutToExpireListDto dto);
         //Task<PagedDto<WorkflowOrderDto>> GetAboutToExpireNodeAsync(AboutToExpireListDto dto, CancellationToken cancellationToken);
-        Task OrderParticiple(string inputStr, string orderId, CancellationToken cancellationToken);
+        Task OrderParticiple(string inputStr, string orderId,DateTime time , CancellationToken cancellationToken);
         Task OrderSensitiveParticiple(string inputStr, string orderId, CancellationToken cancellationToken);
         /// <summary>
         /// 接收外部平台工单
@@ -84,13 +84,6 @@ namespace Hotline.Application.Orders
         /// <returns></returns>
         ISugarQueryable<Order> QueryOrderSource(QueryOrderSourceRequest dto);
 
-		/// <summary>
-		/// 信件来源统计列表
-        /// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		Task<List<OrderSourceHeaderVo>> QueryOrderSourceList(QueryOrderSourceRequest dto);
-
         /// <summary>
         /// 信件来源统计
         /// </summary>
@@ -98,13 +91,6 @@ namespace Hotline.Application.Orders
         /// <returns></returns>
         ISugarQueryable<Order> QueryOrderSourceDetail(QueryOrderSourceDetailRequest dto);
 
-		/// <summary>
-		/// 信件来源分时统计列表
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		Task<List<OrderSourceHeaderVo>> QueryOrderSourceHoursList(QueryOrderSourceRequest dto);
-
 		/// <summary>
 		/// 部门超期统计
 		/// </summary>

+ 9 - 112
src/Hotline.Application/Orders/OrderApplication.cs

@@ -38,6 +38,7 @@ using Hotline.Share.Dtos.Bi;
 using System.Net;
 using PanGu;
 using Hotline.Users;
+using PanGu.Match;
 
 namespace Hotline.Application.Orders;
 
@@ -290,18 +291,20 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     /// </summary>
     /// <param name="inputStr"></param>
     /// <returns></returns>
-    public async Task OrderParticiple(string inputStr, string orderId, CancellationToken cancellationToken)
+    public async Task OrderParticiple(string inputStr, string orderId,DateTime time, CancellationToken cancellationToken)
     {
         var seg = new Segment();
 		ICollection<WordInfo> splitWords = seg.DoSegment(inputStr);
         var words = new List<string>();
         for (int i = 0; i < splitWords.Count; i++)
         {
-            words.Add(splitWords.ElementAt(i).Word);
+            var word = splitWords.ElementAt(i);
+            if (word is { WordType: WordType.SimplifiedChinese, Word.Length: > 1 } )
+	            words.Add(splitWords.ElementAt(i).Word);
 		}
-        var vector = await _orderRepository.Queryable().Where(x => x.Id == orderId).ToListAsync(cancellationToken);
-        if (vector.Any()) await _repositoryts.UpdateVectorAsync(orderId, words, cancellationToken);
-        else await _repositoryts.AddVectorAsync(orderId, DateTime.Now, words, cancellationToken);
+        var vector = await _repositoryts.SearchAsync(orderId, cancellationToken);
+        if (vector != null && vector.Any()) await _repositoryts.UpdateVectorAsync(orderId, words, cancellationToken);
+        else await _repositoryts.AddVectorAsync(orderId, time, words, cancellationToken);
 
         //var words = await _orderWrodRepository.Queryable().Where(x => x.IsEnable == 1 && x.Classify.Contains("普通标签")).Select(x => x.Tag).ToListAsync(cancellationToken);
         //var res = new List<string>();
@@ -531,70 +534,6 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .Where(d => d.SourceChannel != null && d.SourceChannel != "");
     }
 
-    /// <summary>
-    /// 信件来源统计列表
-    /// </summary>
-    /// <param name="dto"></param>
-    /// <returns></returns>
-    public async Task<List<OrderSourceHeaderVo>> QueryOrderSourceList(QueryOrderSourceRequest dto)
-    {
-        if (dto.EndTime.HasValue)
-            dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
-        var data = await _orderRepository.Queryable()
-            .WhereIF(dto.StartTime.HasValue, d => d.CreationTime >= dto.StartTime)
-            .WhereIF(dto.EndTime.HasValue, d => d.CreationTime <= dto.EndTime)
-            .WhereIF(dto.IdentityType.HasValue, d => d.IdentityType == dto.IdentityType)
-            .Where(d => d.SourceChannel != null && d.SourceChannel != "")
-            .GroupBy(d => new { Time = d.CreationTime.ToString("yyyy-MM-dd") })
-            .Select(d => new OrderSourceHeaderVo
-            {
-                Time = d.CreationTime.ToString("yyyy-MM-dd"),
-                Phone = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "RGDH", 1, 0)),
-                Web = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "YTW", 1, 0)),
-                Rests = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "QT", 1, 0)),
-                Created = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "ZJ", 1, 0)),
-                WeChat = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "WX", 1, 0)),
-                App = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "AP", 1, 0)),
-                WisdomYB = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "ZHYB", 1, 0)),
-                Platform = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "ZZPT", 1, 0)),
-                Platform12328 = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "S12328", 1, 0)),
-                MayorAndNetizens = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "SZYSM", 1, 0)),
-                MediaYB = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "YBRMT", 1, 0)),
-                Platform12345 = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "S12345", 1, 0)),
-                Interaction = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "SZMHD", 1, 0)),
-                ServiceYB = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "YBS", 1, 0)),
-                CityTransfer = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "SZHZ", 1, 0)),
-                Platform110 = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "YB110", 1, 0)),
-                NoService = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "SMZXBNCS", 1, 0)),
-                Iyb = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "IYB", 1, 0))
-            }).ToListAsync();
-        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)
-        };
-        data.Add(totalVo);
-        return data;
-    }
-
-
 	/// <summary>
 	/// 信件来源统计明细
 	/// </summary>
@@ -604,54 +543,12 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     {
 
         return _orderRepository.Queryable()
-            .WhereIF(string.IsNullOrEmpty(dto.SourceChannel), d => d.SourceChannel == dto.SourceChannel)
+            .WhereIF(!string.IsNullOrEmpty(dto.SourceChannel), d => d.SourceChannel == dto.SourceChannel)
             .WhereIF(dto.Time.HasValue, d => d.CreationTime.ToString("yyyy-MM-dd") == dto.Time.Value.ToString("yyyy-MM-dd"))
             .WhereIF(dto.IdentityType.HasValue, d => d.IdentityType == dto.IdentityType)
             .Where(d => d.SourceChannel != null && d.SourceChannel != "");
     }
 
-	/// <summary>
-	/// 信件来源分时统计列表
-	/// </summary>
-	/// <param name="dto"></param>
-	/// <returns></returns>
-	public async Task<List<OrderSourceHeaderVo>> QueryOrderSourceHoursList(QueryOrderSourceRequest dto)
-	{
-		if (dto.EndTime.HasValue)
-			dto.EndTime = dto.EndTime.Value.AddDays(1).AddSeconds(-1);
-
-        var data =await _orderRepository.Queryable()
-			.WhereIF(dto.StartTime.HasValue, d => d.CreationTime >= dto.StartTime)
-			.WhereIF(dto.EndTime.HasValue, d => d.CreationTime <= dto.EndTime)
-			.WhereIF(dto.IdentityType.HasValue, d => d.IdentityType == dto.IdentityType)
-			.Where(d => d.SourceChannel != null && d.SourceChannel != "")
-			.GroupBy(d => new { Time = d.CreationTime.ToString("HH") })
-			.Select(d => new OrderSourceHeaderVo
-			{
-				Time = d.CreationTime.ToString("HH")+":00 - " + d.CreationTime.ToString("HH")+":59",
-                TimeSort = d.CreationTime.ToString("HH"),
-				Phone = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "RGDH", 1, 0)),
-				Web = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "YTW", 1, 0)),
-				Rests = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "QT", 1, 0)),
-				Created = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "ZJ", 1, 0)),
-				WeChat = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "WX", 1, 0)),
-				App = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "AP", 1, 0)),
-				WisdomYB = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "ZHYB", 1, 0)),
-				Platform = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "ZZPT", 1, 0)),
-				Platform12328 = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "S12328", 1, 0)),
-				MayorAndNetizens = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "SZYSM", 1, 0)),
-				MediaYB = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "YBRMT", 1, 0)),
-				Platform12345 = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "S12345", 1, 0)),
-				Interaction = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "SZMHD", 1, 0)),
-				ServiceYB = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "YBS", 1, 0)),
-				CityTransfer = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "SZHZ", 1, 0)),
-				Platform110 = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "YB110", 1, 0)),
-				NoService = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "SMZXBNCS", 1, 0)),
-				Iyb = SqlFunc.AggregateSum(SqlFunc.IIF(d.SourceChannelCode == "IYB", 1, 0))
-			}).OrderBy(d=> d.TimeSort).ToListAsync();
-		return data;
-	}
-
 	/// <summary>
 	/// 部门超期统计
 	/// </summary>

+ 1 - 1
src/Hotline.Application/StatisticalReport/OrderReportApplication.cs

@@ -1411,7 +1411,7 @@ namespace Hotline.Application.StatisticalReport
                })
                 .Select((it, o) => new DepartmentAcceptanceTypeStatisticsDto
                 {
-                    OrgName = it.OrgCode == "001" ? "热线中心" : o.Name,
+                    OrgName = it.OrgCode == "001" ? "市民热线服务中心" : o.Name,
                     OrgCode = it.OrgCode,
                     OrgType = o.OrgType == EOrgType.County ? "区县部门" : "市直部门",
                     ZxAllCount = SqlFunc.AggregateSum(SqlFunc.IIF(it.AcceptTypeCode == "10", 1, 0)),

+ 2 - 2
src/Hotline.Application/Subscribers/DatasharingSubscriber.cs

@@ -232,7 +232,7 @@ namespace Hotline.Application.Subscribers
             model.ApplyContent = dto.RemindReasion;
             model.OrderId = order.Id;
             model.OrgId = "001";
-            model.OrgName = "热线中心";
+            model.OrgName = "市民热线服务中心";
             model.ApplyContent = dto.RemindReasion;
 
             if (!string.IsNullOrEmpty(order.WorkflowId))
@@ -271,7 +271,7 @@ namespace Hotline.Application.Subscribers
             model.OrderId = order.Id;
             model.ReplyLimitTime = dto.WarnTimebf;
             model.OrgId = "001";
-            model.OrgName = "热线中心";
+            model.OrgName = "市民热线服务中心";
 
             if (!string.IsNullOrEmpty(order.WorkflowId))
             {

+ 112 - 8
src/Hotline.Repository.SqlSugar/Orders/OrderRepository.cs

@@ -6,10 +6,14 @@ using Hotline.Settings;
 using Hotline.Settings.Hotspots;
 using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Enums.CallCenter;
+using Hotline.Share.Enums.Order;
 using Hotline.Share.Requests;
 using SqlSugar;
 using System.Data;
+using System.Linq;
+using System.Linq.Dynamic.Core;
 using System.Reflection;
+using System.Reflection.Emit;
 using XF.Domain.Dependency;
 
 namespace Hotline.Repository.SqlSugar.Orders
@@ -572,13 +576,85 @@ namespace Hotline.Repository.SqlSugar.Orders
             return InitDatatTable(dt, dto.AddColumnName);
         }
 
-        /// <summary>
-        /// 处理导出数据
-        /// </summary>
-        /// <param name="dt"></param>
-        /// <param name="AddColumnName"></param>
-        /// <returns></returns>
-        public DataTable InitDatatTable(DataTable dt, List<string> AddColumnName)
+		/// <summary>
+		/// 信件来源统计
+		/// </summary>
+		/// <param name="dto"></param>
+		/// <returns></returns>
+		public async Task<object> OrderSource(QueryOrderSourceRequest dto)
+		{
+			var listOrder = Db.Queryable<Order>()
+				 .Where(p => p.CreationTime >= dto.StartTime && p.CreationTime <= dto.EndTime)
+				 .WhereIF(dto.IdentityType != null, p => p.IdentityType == dto.IdentityType)
+				 .Select(p => new
+				 {
+					 SourceChannelCode = p.SourceChannelCode,
+					 Hour = p.CreationTime.ToString("yyyy-MM-dd")
+				 })
+			   .MergeTable();
+
+			var listOrg = await Db.Queryable<SystemDicData>()
+			  .LeftJoin(listOrder, (s, p) => s.DicDataValue == p.SourceChannelCode)
+			  .Where((s, p) => s.DicTypeCode == "SourceChannel")
+			  .GroupBy((s, p) => s.DicDataValue).GroupBy((s, p) => s.DicDataName)
+			  .GroupBy((s, p) => p.Hour)
+			  .OrderBy((s, p) => p.Hour)
+			  .Select((s, p) => new
+			  {
+				  Hour = SqlFunc.IIF(p.Hour == null || p.Hour == "", "0", p.Hour),
+				  count = SqlFunc.AggregateSum(SqlFunc.IIF(p.SourceChannelCode != null && p.SourceChannelCode != "", 1, 0)),
+				  DicDataValue = s.DicDataValue,
+				  DicDataName = s.DicDataName
+			  })
+			  .ToPivotListAsync(p => p.DicDataValue, p => p.Hour, p => p.Sum(x => x.count));
+			return listOrg;
+
+		}
+
+		/// <summary>
+		/// 信件来源统计---导出
+		/// </summary>
+		/// <param name="dto"></param>
+		/// <returns></returns>
+		public async Task<DataTable> OrderSourceExport(QueryOrderSourceRequest dto)
+		{
+			var listOrder = Db.Queryable<Order>()
+				 .Where(p => p.CreationTime >= dto.StartTime && p.CreationTime <= dto.EndTime)
+				 .WhereIF(dto.IdentityType != null, p => p.IdentityType == dto.IdentityType)
+				 .Select(p => new
+				 {
+					 SourceChannelCode = p.SourceChannelCode,
+					 Hour = p.CreationTime.ToString("yyyy-MM-dd")
+				 })
+			   .MergeTable();
+
+			var listOrg = await Db.Queryable<SystemDicData>()
+			  .LeftJoin(listOrder, (s, p) => s.DicDataValue == p.SourceChannelCode)
+			  .Where((s, p) => s.DicTypeCode == "SourceChannel")
+			  .GroupBy((s, p) => s.DicDataValue).GroupBy((s, p) => s.DicDataName)
+			  .GroupBy((s, p) => p.Hour)
+			  .OrderBy((s, p) => p.Hour)
+			  .Select((s, p) => new
+			  {
+				  Hour = SqlFunc.IIF(p.Hour == null || p.Hour == "", "0", p.Hour),
+				  count = SqlFunc.AggregateSum(SqlFunc.IIF(p.SourceChannelCode != null && p.SourceChannelCode != "", 1, 0)),
+				  DicDataValue = s.DicDataValue,
+				  DicDataName = s.DicDataName
+			  })
+			  .ToPivotTableAsync(p => p.DicDataName, p => p.Hour, p => p.Sum(x => x.count));
+				listOrg.Columns["Hour"].ColumnName = "日期";
+				if (listOrg.Rows[0][listOrg.Rows.Count - 1] == "0")
+				    listOrg.Rows[listOrg.Rows.Count - 1].Delete();
+			return InitDatatTable(listOrg, dto.AddColumnName);
+		}
+
+		/// <summary>
+		/// 处理导出数据
+		/// </summary>
+		/// <param name="dt"></param>
+		/// <param name="AddColumnName"></param>
+		/// <returns></returns>
+		public DataTable InitDatatTable(DataTable dt, List<string> AddColumnName)
         {
             //修改列名
             if (dt.Columns.Contains("Hour"))
@@ -602,7 +678,8 @@ namespace Hotline.Repository.SqlSugar.Orders
 
             //增加合计
             DataRow totalRow = dt.NewRow();
-            totalRow["时间段"] = "合计";
+            if (dt.Columns[0].ColumnName == "日期") totalRow["日期"] = "合计";
+            else totalRow["时间段"] = "合计";
             for (int i = 1; i < dt.Columns.Count; i++)
             {
                 int sumcount = 0;
@@ -637,6 +714,33 @@ namespace Hotline.Repository.SqlSugar.Orders
             return dt2;
         }
 
+        /// <summary>
+        /// 满意度明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        public ISugarQueryable<OrderVisitDetail> OrgVisitDetailList(OrgVisitDetailListReq dto)
+        {
+            return Db.Queryable<OrderVisitDetail>()
+                .Includes(x => x.OrderVisit, x => x.Order, x => x.OrderScreens)
+                .Includes(x => x.OrderVisit, x => x.Employee)
+                .Where(x => x.OrderVisit.VisitState == EVisitState.Visited && x.VisitTarget == EVisitTarget.Org)
+                .WhereIF(dto.OrgVisitStatisticsType.HasValue, x => x.OrderVisit.Order.ProcessType == (EProcessType)((int)dto.OrgVisitStatisticsType))
+                .WhereIF(!string.IsNullOrEmpty(dto.OrgProcessingResults), x => SqlFunc.JsonField(x.OrgProcessingResults, "Key") == dto.OrgProcessingResults)
+                .WhereIF(!string.IsNullOrEmpty(dto.VisitUser), x => x.OrderVisit.Employee.Name.Contains(dto.VisitUser))
+                .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.OrderVisit.Order.No == dto.No)
+                .WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.OrderVisit.Order.Title.Contains(dto.Title))
+                .WhereIF(dto.OrgCodes.Any(), x => dto.OrgCodes.Contains(x.VisitOrgCode))
+                .WhereIF(dto.HotspotIds.Any(), x => dto.HotspotIds.Contains(x.OrderVisit.Order.HotspotId))
+                .WhereIF(dto.Channels.Any(), x => dto.Channels.Contains(x.OrderVisit.Order.SourceChannelCode))
+                .WhereIF(dto.CreationTimeStart.HasValue, x => x.OrderVisit.Order.CreationTime >= dto.CreationTimeStart) //受理时间开始
+                .WhereIF(dto.CreationTimeEnd.HasValue, x => x.OrderVisit.Order.CreationTime <= dto.CreationTimeEnd) //受理时间结束
+                .WhereIF(dto.ActualHandleTimeStart.HasValue, x => x.OrderVisit.Order.ActualHandleTime >= dto.ActualHandleTimeStart) //办结时间开始
+                .WhereIF(dto.ActualHandleTimeEnd.HasValue, x => x.OrderVisit.Order.ActualHandleTime <= dto.ActualHandleTimeEnd); //办结时间结束
+        }
+
+
+
         public ISugarQueryable<SelectOrderId> OrderListUnionAll(ISugarQueryable<SelectOrderId> t1, ISugarQueryable<SelectOrderId> t2)
         {
             return Db.UnionAll(t1, t2).Select(it => new SelectOrderId { Id = it.Id }).MergeTable();

+ 11 - 2
src/Hotline.Repository.SqlSugar/Ts/BaseRepositoryTextSearch.cs

@@ -84,9 +84,18 @@ FROM order_ts, to_tsquery('simple', 'bb') query WHERE "Vector" @@ query ORDER BY
          */
     }
 
-    #region private method
+    public async Task<List<TEntity>> SearchAsync(string id, CancellationToken cancellationToken)
+    {
+	    var tableName = typeof(TEntity).Name.ToSnakeCase();
+	    var sql =
+		    $"SELECT * FROM {tableName} WHERE \"Id\" ='{id}' ";
+	    return await _db.Ado.SqlQueryAsync<TEntity>(sql, null, cancellationToken);
+
+    }
+
+	#region private method
 
-    private static string CreateVectorSql(ICollection<NpgsqlWeight> weights)
+	private static string CreateVectorSql(ICollection<NpgsqlWeight> weights)
     {
         var setweghtStrings = weights.Select(d => $"setweight(to_tsvector('simple', '{d.Text}'), '{d.Weight}')");
         var vectorString = string.Join(" || ", setweghtStrings);

+ 8 - 0
src/Hotline.Repository.SqlSugar/Ts/IRepositoryTextSearch.cs

@@ -28,4 +28,12 @@ public interface IRepositoryTextSearch<TEntity>
     /// <param name="cancellationToken"></param>
     /// <returns></returns>
     Task<List<TEntity>> SearchAsync(IReadOnlyList<string> texts, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 根据id获取
+    /// </summary>
+    /// <param name="id"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<List<TEntity>> SearchAsync(string id, CancellationToken cancellationToken);
 }

+ 100 - 0
src/Hotline.Share/Dtos/Order/OrderBiDto.cs

@@ -271,6 +271,106 @@ namespace Hotline.Share.Dtos.Order
     }
 
 
+	public class OrgVisitDetailListResp
+	{
+		/// <summary>
+		/// 工单ID
+		/// </summary>
+		public string Id { get; set; }
+
+		/// <summary>
+		/// 回访ID
+		/// </summary>
+		public string VisitId { get; set; }
+		/// <summary>
+		/// 工单编号
+		/// </summary>
+		public string No { get; set; }
+
+		/// <summary>
+		/// 重办次数
+		/// </summary>
+		public string ReTransactNum { get; set; }
+
+		/// <summary>
+		/// 甄别状态
+		/// </summary>
+		public EScreenStatus? OrderScreenStatus { get; set; }
+		public string? OrderScreenStatusText => OrderScreenStatus?.GetDescription();
+
+        /// <summary>
+        /// 回访内容
+        /// </summary>
+        public string VisitContent { get; set; }
+
+		/// <summary>
+		/// 热点全称
+		/// </summary>
+		public string HotspotSpliceName { get; set; }
+
+		/// <summary>
+		/// 一级部门
+		/// </summary>
+		public string OrgLevelOneName { get; set; }
+
+		/// <summary>
+		/// 办结部门
+		/// </summary>
+		public string ActualHandleOrgName { get; set; }
+
+		/// <summary>
+		/// 受理时间
+		/// </summary>
+		public DateTime CreationTime { get; set; }
+
+		/// <summary>
+		/// 工单标题
+		/// </summary>
+		public string Title { get; set; }
+
+		/// <summary>
+		/// 回访人
+		/// </summary>
+		public string VisitUser { get; set; }
+
+		/// <summary>
+		/// 回访部门
+		/// </summary>
+		public string VisitOrgName { get; set; }
+
+		/// <summary>
+		/// 回访方式
+		/// </summary>
+		public EVisitType? VisitType { get; set; }
+
+		public string? VisitTypeText => VisitType?.GetDescription();
+
+		/// <summary>
+		/// 回访时间
+		/// </summary>
+		public DateTime VisitTime { get; set; }
+
+		/// <summary>
+		/// 满意度
+		/// </summary>
+		public string OrgProcessingResults { get; set; }
+
+		/// <summary>
+		/// 受理内容
+		/// </summary>
+		public string Content { get; set; }
+
+		/// <summary>
+		/// 承办意见
+		/// </summary>
+		public string FileOpinion { get; set;}
+
+		/// <summary>
+		/// 办结时间
+		/// </summary>
+		public DateTime? FiledTime { get; set; }
+    }
+
 
 
     public class VisitAndOrgSatisfactionStatisticsDto

+ 14 - 0
src/Hotline.Share/Enums/Order/EOrgVisitStatisticsType.cs

@@ -0,0 +1,14 @@
+
+using System.ComponentModel;
+
+namespace Hotline.Share.Enums.Order
+{
+    public enum EOrgVisitStatisticsType
+    {
+        [Description("中心统计")]
+        CallCenter = 10,
+
+        [Description("部门统计")]
+        Org = 20,
+    }
+}

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

@@ -253,6 +253,11 @@ public record QueryOrderSourceRequest : ReportPagedRequest
     /// 来电/信人身份
     /// </summary>
     public EIdentityType? IdentityType { get; set; }
+
+    /// <summary>
+    /// 导出列名
+    /// </summary>
+    public List<string> AddColumnName { get; set; }
 }
 
 public record QueryOrderSourceDetailRequest : QueryOrderSourceRequest
@@ -289,3 +294,59 @@ public record TimeSharingPagedKeywordRequest : PagedKeywordRequest
     public List<string> AddColumnName { get; set; }
 }
 
+
+public record OrgVisitDetailListReq: PagedKeywordRequest
+{
+    /// <summary>
+    /// 部门分类
+    /// </summary>
+    public EOrgVisitStatisticsType? OrgVisitStatisticsType { get; set; }
+
+    /// <summary>
+    /// 办件结果
+    /// </summary>
+    public string? OrgProcessingResults { get; set; }
+
+    /// <summary>
+    /// 回访人
+    /// </summary>
+    public string? VisitUser { get; set; }
+
+    /// <summary>
+    /// 工单编号
+    /// </summary>
+    public string? No { get; set; }
+
+    /// <summary>
+    /// 工单标题
+    /// </summary>
+    public string? Title { get; set; }
+
+    /// <summary>
+    /// 回访部门
+    /// </summary>
+    public List<string> OrgCodes { get; set; } = new();
+
+    /// <summary>
+    /// 热点分类
+    /// </summary>
+    public List<string> HotspotIds { get; set; } = new();
+
+    /// <summary>
+    /// 来源渠道(√)
+    /// </summary>
+    public List<string> Channels { get; set; } = new();
+
+    /// <summary>
+    /// 受理时间(工单创建时间)(√)
+    /// </summary>
+    public DateTime? CreationTimeStart { get; set; }
+    public DateTime? CreationTimeEnd { get; set; }
+
+    /// <summary>
+    /// 办结时间(√)
+    /// </summary>
+    public DateTime? ActualHandleTimeStart { get; set; }
+    public DateTime? ActualHandleTimeEnd { get; set; }
+}
+

+ 2 - 2
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -1449,7 +1449,7 @@ namespace Hotline.FlowEngine.Workflows
             if (nextStepDefine.BusinessType is EBusinessType.Center or EBusinessType.Send)
             {
                 workflow.UpdateActualStepWhenAssign(nextSteps.First(), actualHandleOrgCode: OrgSeedData.CenterId,
-                    actualHandleOrgName: "热线中心");
+                    actualHandleOrgName: "市民热线服务中心");
             }
             else
             {
@@ -1466,7 +1466,7 @@ namespace Hotline.FlowEngine.Workflows
             //    if (nextStepDefine.BusinessType is EBusinessType.Center or EBusinessType.Send)
             //    {
             //        workflow.UpdateActualStepWhenAssign(firstSteps.First(), actualHandleOrgCode: OrgSeedData.CenterId,
-            //            actualHandleOrgName: "热线中心");
+            //            actualHandleOrgName: "市民热线服务中心");
             //    }
             //    else
             //    {

+ 23 - 1
src/Hotline/Orders/IOrderRepository.cs

@@ -82,7 +82,29 @@ namespace Hotline.Orders
         /// <returns></returns>
         Task<DataTable> OrderSourceTimeExport(TimeSharingPagedKeywordRequest dto);
 
-    }
+        /// <summary>
+        /// 满意度明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        ISugarQueryable<OrderVisitDetail> OrgVisitDetailList(OrgVisitDetailListReq dto);
+
+        /// <summary>
+        /// 信件来源统计
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        Task<object> OrderSource(QueryOrderSourceRequest dto);
+
+        /// <summary>
+        /// 信件来源统计 -- 导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+		Task<DataTable> OrderSourceExport(QueryOrderSourceRequest dto);
+
+
+	}
 
     public interface IOrderScreenRepository : IRepositoryWorkflow<OrderScreen>
     {

+ 18 - 8
src/Hotline/dataview.md

@@ -19,7 +19,11 @@ CASE 	WHEN "Status">=300 and "ExpiredTime">"FiledTime" THEN '正常'
 	ELSE '未知'
 END AS "IsOverExpiredTime",
 "SourceChannel" AS "Source" , 
-"TransferPhone" AS "TransferPhone" ,
+CASE 
+	WHEN "TransferPhone" is null or "TransferPhone"='undefined' THEN '12345'
+	ELSE
+		"TransferPhone"
+END AS "TransferPhone" ,
 "ActualHandleStepName" AS "ActualHandleStepName" ,
 "ReTransactNum" AS "ReTransactNum" , 
 (select CASE "screentemp"."Status"
@@ -32,13 +36,19 @@ END AS "OrderScreenStatus"
  from order_screen screentemp WHERE "OrderId"="ordertemp"."Id" order by "CreationTime" DESC LIMIT 1) as "OrderScreenStatus", 
 "No" AS "No" , 
 "ProvinceNo" AS "ProvinceNo" , 
-"CreationTime" AS "StartTime" , 
+to_char("CreationTime", 'YYYY-MM-DD HH24:MI:SS') AS "StartTime" , 
 "Title" AS "Title" , 
-"ExpiredTime" AS "ExpiredTime" , 
+to_char("ExpiredTime", 'YYYY-MM-DD HH24:MI:SS') AS "ExpiredTime" , 
 "OrgLevelOneName" AS "OrgLevelOneName" , 
-"OrgLevelTwoName" AS "OrgLevelTwoName" , 
-"AcceptorOrgName" AS "AcceptorOrgName" , 
-"FiledTime" AS "FiledTime" , 
+
+CASE 
+	WHEN length("ActualHandleOrgCode")>=9 THEN
+		(select "Name" from system_organize orgtemp WHERE orgtemp."Id"="substring"("ordertemp"."ActualHandleOrgCode", 1, 9))
+	ELSE
+		'-'
+END AS "OrgLevelTwoName" , 
+"ActualHandleOrgName" AS "ActualHandleOrgName" , 
+to_char("FiledTime", 'YYYY-MM-DD HH24:MI:SS') AS "FiledTime" , 
 "AcceptType" AS "AcceptType" , 
 "HotspotName" AS "HotspotName",
 "HotspotSpliceName" AS "HotspotSpliceName",
@@ -71,7 +81,7 @@ END AS "FromGender" ,
 "Content" AS "Content" , 
 "ActualOpinion" AS "ActualOpinion" ,
 "FileOpinion" AS "FileOpinion" ,
-"Id" AS "SugarNav_Id" FROM "order" ordertemp  WHERE (( "CreationTime" >= '2024-06-26' ) AND ( "CreationTime" < '2024-07-3' ))  AND ( "IsDeleted" = FALSE )ORDER BY "CreationTime" ASC) aaa
+"Id" AS "SugarNav_Id" FROM "order" ordertemp  WHERE (( "CreationTime" >= '2024-03-29' ) AND ( "CreationTime" < '2024-07-3' ))  AND ( "IsDeleted" = FALSE )ORDER BY "CreationTime" ASC) aaa
 left join 
 (select DISTINCT CASE visitdetailtemp."SeatEvaluate"
 	WHEN 0 THEN '默认满意'
@@ -85,5 +95,5 @@ left join
 END AS "SeatVisitResult",visittemp."OrderId" as "OrderId"
  from order_visit visittemp
 left join order_visit_detail visitdetailtemp on visittemp."Id"= visitdetailtemp."VisitId"  
-where visittemp."CreationTime">='2024-06-26' and visitdetailtemp."VisitTarget"=10 AND visittemp."VisitState"=30 ) bbb on aaa."SugarNav_Id"=bbb."OrderId"
+where visittemp."CreationTime">='2024-03-29' and visitdetailtemp."VisitTarget"=10 AND visittemp."VisitState"=30 ) bbb on aaa."SugarNav_Id"=bbb."OrderId";