Jelajahi Sumber

Merge branch 'release'

xf 9 bulan lalu
induk
melakukan
e444354635

+ 3 - 3
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -737,7 +737,7 @@ namespace Hotline.Api.Controllers.Bi
                     AcceptType = x.AcceptType,
                     OneHotspot = SqlFunc.Substring(x.HotspotSpliceName, 0, SqlFunc.CharIndex("-", x.HotspotSpliceName + "-")),
                     Id = x.Id
-                }).MergeTable()
+                }).MergeTable().Where(x => x.OneHotspot != "非受理范围")
                 .GroupBy(x => new { x.OneHotspot })
                 .Select(x => new AcceptTypeTop10Vo
                 {
@@ -2017,9 +2017,9 @@ namespace Hotline.Api.Controllers.Bi
             .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.StartsWith(dto.Keyword!)) //标题
             .WhereIF(!string.IsNullOrEmpty(dto.ProvinceNo), d => d.ProvinceNo == dto.ProvinceNo) //省本地编号
             .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No == dto.No) //工单编码
-            .WhereIF(!string.IsNullOrEmpty(dto.AcceptType), d => d.AcceptType == dto.AcceptType)//受理类型
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptType), d => d.AcceptTypeCode == dto.AcceptType)//受理类型
             //.WhereIF(dto.AcceptTypes.Any(), d => dto.AcceptTypes.Contains(d.AcceptTypeCode)) //受理类型
-            .WhereIF(!string.IsNullOrEmpty(dto.Channel), d => d.SourceChannel == dto.Channel)
+            .WhereIF(!string.IsNullOrEmpty(dto.Channel), d => d.SourceChannelCode == dto.Channel)
             //.WhereIF(dto.Channels.Any(), d => dto.Channels.Contains(d.SourceChannelCode)) //来源渠道
             //.WhereIF(dto.HotspotIds.Any(), d => dto.HotspotIds.Contains(d.HotspotId)) //热点类型
             .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), d => d.HotspotSpliceName != null && d.HotspotSpliceName.Contains(dto.Hotspot))

+ 16 - 9
src/Hotline.Api/Controllers/IPPbxController.cs

@@ -25,6 +25,7 @@ using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Options;
 using Newtonsoft.Json;
+using System.Threading;
 using Tr.Sdk;
 using Tr.Sdk.Blacklist;
 using Tr.Sdk.Tels;
@@ -171,7 +172,6 @@ namespace Hotline.Api.Controllers
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
-        [Permission(EPermission.AddBlackList)]
         [HttpPost("add-blacklist")]
         public async Task AddBlacklist([FromBody] TrAddBlacklistDto dto)
         {
@@ -183,7 +183,6 @@ namespace Hotline.Api.Controllers
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
-        [Permission(EPermission.RemoveBlacklist)]
         [HttpPost("remove-blacklist")]
         public async Task DelBlacklist([FromBody] TrDelBlacklistDto dto)
         {
@@ -194,7 +193,6 @@ namespace Hotline.Api.Controllers
         /// 查询黑白名单
         /// </summary>
         /// <returns></returns>
-        [Permission(EPermission.QueryPagedBlack)]
         [HttpGet("query-blacklist")]
         public async Task<IReadOnlyList<TrQueryBlacklistResponseDto>> QueryBlacklist([FromQuery] TrQueryBlacklistDto dto)
         {
@@ -501,12 +499,21 @@ namespace Hotline.Api.Controllers
                         {
 							var setting = _systemSettingCacheManager.GetSetting(SettingConstants.ViteRecordPrefix);
 							//await _aiQualityService.CreateAiOrderQualityTask(quality, model, order, setting?.SettingValue[0], HttpContext.RequestAborted);
-                            await _aiQualityService.CreateAiOrderQualityTask(
-                                quality,
-                                model.RecordingAbsolutePath,
-                                model.CPN,
-                                model.CreatedTime,
-                                order, setting?.SettingValue[0], HttpContext.RequestAborted);
+
+							try
+							{
+								 _aiQualityService.CreateAiOrderQualityTask(
+									quality,
+									model.RecordingAbsolutePath,
+									model.CPN,
+									model.CreatedTime,
+									order, setting?.SettingValue[0], HttpContext.RequestAborted);
+							}
+							catch (Exception e)
+							{
+								_logger.LogError($"写入智能质检异常!, \r\n{e.Message}");
+							}
+						
                         }
                     }
                 }

+ 55 - 2
src/Hotline.Api/Controllers/OrderController.cs

@@ -382,6 +382,38 @@ public class OrderController : BaseController
 
                     visitedDetail.Add(seatDetail);
                     await _orderVisitedDetailRepository.AddRangeAsync(visitedDetail, HttpContext.RequestAborted);
+
+                    if (orderVisit.VisitState == EVisitState.Visited)
+                    {
+                        //推省上
+                        await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisited,
+                            new PublishVisitDto()
+                            {
+                                Order = _mapper.Map<OrderDto>(order),
+                                No = orderVisit.No,
+                                VisitType = orderVisit.VisitType,
+                                VisitName = orderVisit.CreatorName,
+                                VisitTime = orderVisit.VisitTime,
+                                VisitRemark = orderVisit.NowEvaluate?.Value,
+                                AreaCode = order.AreaCode!,
+                                SubjectResultSatifyCode = orderVisit.NowEvaluate?.Key,
+                                FirstSatisfactionCode = orderVisit.NowEvaluate?.Key,
+                                ClientGuid = ""
+                            }, cancellationToken: HttpContext.RequestAborted);
+                    }
+
+                    //推门户
+                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisitedWeb, new PublishVisitAllDto()
+                    {
+                        Id = orderVisit.Id,
+                        Order = _mapper.Map<OrderDto>(order),
+                        OrderVisitDetails = _mapper.Map<List<VisitDetailDto>>(orderVisit.OrderVisitDetails),
+                        VisitName = _sessionContext.UserName,
+                        VisitTime = orderVisit.VisitTime,
+                        VisitType = orderVisit.VisitType,
+                        VisitState = orderVisit.VisitState,
+                        PublishTime = orderVisit.PublishTime,
+                    }, cancellationToken: HttpContext.RequestAborted);
                 }
                 catch
                 {
@@ -489,6 +521,27 @@ public class OrderController : BaseController
 
         visitedDetail.Add(seatDetail);
         await _orderVisitedDetailRepository.AddRangeAsync(visitedDetail, HttpContext.RequestAborted);
+
+
+        if (orderVisit.VisitState == EVisitState.Visited)
+        {
+            //推省上
+            await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisited,
+                new PublishVisitDto()
+                {
+                    Order = _mapper.Map<OrderDto>(order),
+                    No = orderVisit.No,
+                    VisitType = orderVisit.VisitType,
+                    VisitName = orderVisit.CreatorName,
+                    VisitTime = orderVisit.VisitTime,
+                    VisitRemark = orderVisit.NowEvaluate?.Value,
+                    AreaCode = order.AreaCode!,
+                    SubjectResultSatifyCode = orderVisit.NowEvaluate?.Key,
+                    FirstSatisfactionCode = orderVisit.NowEvaluate?.Key,
+                    ClientGuid = ""
+                }, cancellationToken: HttpContext.RequestAborted);
+        }
+
         //推送回访信息
         //推门户
         await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisitedWeb, new PublishVisitAllDto()
@@ -4641,9 +4694,9 @@ public class OrderController : BaseController
             .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
                 d => d.Title.Contains(dto.Keyword!) || d.No.Contains(dto.Keyword!))
             //.WhereIF(!string.IsNullOrEmpty(dto.Content), d => d.Content.Contains(dto.Content!))
-            .WhereIF(!string.IsNullOrEmpty(dto.AcceptType), d => d.AcceptType == dto.AcceptType)//受理类型
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptType), d => d.AcceptTypeCode == dto.AcceptType)//受理类型
                                                                                                 //.WhereIF(dto.AcceptTypes.Any(), d => dto.AcceptTypes.Contains(d.AcceptTypeCode)) //受理类型
-            .WhereIF(!string.IsNullOrEmpty(dto.Channel), d => d.SourceChannel == dto.Channel)//来源渠道
+            .WhereIF(!string.IsNullOrEmpty(dto.Channel), d => d.SourceChannelCode == dto.Channel)//来源渠道
             .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), d => d.HotspotSpliceName != null && d.HotspotSpliceName.Contains(dto.Hotspot))
             .WhereIF(!string.IsNullOrEmpty(dto.TransferPhone), d => d.TransferPhone.Contains(dto.TransferPhone!))
             .WhereIF(!string.IsNullOrEmpty(dto.OrgName), d => d.CurrentHandleOrgName == dto.OrgName)//接办部门

+ 2 - 2
src/Hotline.Api/Controllers/PushMessageController.cs

@@ -127,8 +127,8 @@ namespace Hotline.Api.Controllers
                          d.CreatorOrgName.Contains(pagedDto.Keyword!))
                 .WhereIF(pagedDto.StartTime.HasValue, d => d.SendTime >= pagedDto.StartTime)
                 .WhereIF(pagedDto.EndTime.HasValue, d => d.SendTime <= pagedDto.EndTime)
-                .WhereIF(!string.IsNullOrEmpty(pagedDto.UserName), d => d.Name == pagedDto.UserName)
-                 .WhereIF(!string.IsNullOrEmpty(pagedDto.TelNumber), d => d.TelNumber == pagedDto.TelNumber)
+                .WhereIF(!string.IsNullOrEmpty(pagedDto.UserName), d => d.Name.Contains(pagedDto.UserName))
+                 .WhereIF(!string.IsNullOrEmpty(pagedDto.TelNumber), d => d.TelNumber.Contains(pagedDto.TelNumber))
                 .OrderByDescending(it => it.CreationTime)
                 .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
 

+ 14 - 7
src/Hotline.Api/Controllers/QualityController.cs

@@ -755,13 +755,20 @@ namespace Hotline.Api.Controllers
                 }
 
                 var setting = _systemSettingCacheManager.GetSetting(SettingConstants.ViteRecordPrefix);
-                await _aiQualityService.CreateAiOrderQualityTask(
-                    quality,
-                    audioFile,
-                    fromNo,
-                    callStartTime,
-                    order, setting?.SettingValue[0], HttpContext.RequestAborted);
-                await _qualitey.UpdateAsync(quality, HttpContext.RequestAborted);
+                try
+                {
+					 _aiQualityService.CreateAiOrderQualityTask(
+						quality,
+						audioFile,
+						fromNo,
+						callStartTime,
+						order, setting?.SettingValue[0], HttpContext.RequestAborted);
+				}
+                catch (Exception e)
+                {
+	                _logger.LogError($"写入智能质检异常!, \r\n{e.Message}");
+                }
+				await _qualitey.UpdateAsync(quality, HttpContext.RequestAborted);
             }
         }
 

+ 108 - 1
src/Hotline.Api/Controllers/TestController.cs

@@ -8,9 +8,11 @@ using Fw.Utility.Client;
 using Google.Protobuf.WellKnownTypes;
 using Hotline.Ai.Visit;
 using Hotline.Application.ExportExcel;
+using Hotline.Application.FlowEngine;
 using Hotline.Application.JudicialManagement;
 using Hotline.Application.Quality;
 using Hotline.Application.StatisticalReport;
+using Hotline.Authentications;
 using Hotline.CallCenter.BlackLists;
 using Hotline.CallCenter.Calls;
 using Hotline.CallCenter.Configs;
@@ -131,6 +133,7 @@ public class TestController : BaseController
     private readonly IRepository<EnforcementOrders> _enforcementOrdersRepository;
     private readonly IRepository<JudicialManagementOrders> _judicialManagementOrdersRepository;
     private readonly IRepository<EnforcementOrdersHandler> _enforcementOrdersHandlerRepository;
+    private readonly IWorkflowApplication _workflowApplication;
 
     //private readonly ITypedCache<List<User>> _cache;
     //private readonly ICacheManager<User> _cache;
@@ -180,7 +183,8 @@ public class TestController : BaseController
    IOrderReportApplication orderReportApplication,
 IRepository<EnforcementOrders> enforcementOrdersRepository,
 IRepository<JudicialManagementOrders> judicialManagementOrdersRepository,
-IRepository<EnforcementOrdersHandler> enforcementOrdersHandlerRepository
+IRepository<EnforcementOrdersHandler> enforcementOrdersHandlerRepository,
+        IWorkflowApplication workflowApplication
         )
     {
         _logger = logger;
@@ -223,6 +227,8 @@ IRepository<EnforcementOrdersHandler> enforcementOrdersHandlerRepository
         _enforcementOrdersRepository = enforcementOrdersRepository;
         _judicialManagementOrdersRepository = judicialManagementOrdersRepository;
         _enforcementOrdersHandlerRepository = enforcementOrdersHandlerRepository;
+        _workflowApplication = workflowApplication;
+
     }
     /// <summary>
     /// 处理司法工单数据
@@ -1004,4 +1010,105 @@ IRepository<EnforcementOrdersHandler> enforcementOrdersHandlerRepository
         return $"{publicKey} \r\n {privateKey}";
     }
 
+    /// <summary>
+    /// 处理工单流程错误数据   话务部直接归档件  没有归档节点
+    /// </summary>
+    /// <param name="StartTime"></param>
+    /// <param name="EndTime"></param>
+    /// <returns></returns>
+    [HttpGet("oders_workflow_step")]
+    [AllowAnonymous]
+    public async Task AddJudicialManagementOrders()
+    {
+
+        var steps = await _workflowStepRepository.Queryable()
+            .LeftJoin<Order>((ws, d) => ws.ExternalId == d.Id)
+            .Where((ws, d) => d.Status == EOrderStatus.Handling && ws.NextStepCode == "end" && ws.Status == EWorkflowStepStatus.Handled && ws.StepType == EStepType.Start)
+            .ToListAsync(HttpContext.RequestAborted);
+
+        _logger.LogInformation($"取到数据 {steps.Count} 条");
+        foreach (var item in steps)
+        {
+            ///组装数据
+            //Workflow workflow
+            Workflow workflow = await _workflowDomainService.GetWorkflowAsync(item.WorkflowId, withDefine: true, withSteps: true,
+                cancellationToken: HttpContext.RequestAborted);
+            //WorkflowStep startStep
+            var startStep = workflow.Steps.FirstOrDefault(x => x.StepType == EStepType.Start);
+            if (startStep is null) continue;
+            //BasicWorkflowDto dto
+            BasicWorkflowDto dto = new BasicWorkflowDto
+            {
+                NextStepCode = "end",
+                NextStepName = "结束",
+                BackToCountersignEnd = false,
+                FlowDirection = null,
+                HandlerType = 0,
+                StepType = 0,
+                NextHandlers = new List<FlowStepHandler>(),
+                IsSms = false,
+                NextMainHandler = "",
+                IsStartCountersign = false,
+                External = new External
+                {
+                    TimeLimit = null,
+                    TimeLimitUnit = null,
+                    IsPoliceReturn = false,
+                    IsResolved = false,
+                },
+                BusinessType = EBusinessType.File,
+                ReviewResult = 0,
+                Remark = null,
+                Opinion = startStep.Opinion,
+                Files = new List<Share.Dtos.File.FileDto>()
+            };
+            //ISessionContext current
+            ISessionContext current = new ProvinceSessionContext
+            {
+                UserId = startStep.HandlerId,
+                UserName = startStep.HandlerName,
+                OrgId = startStep.HandlerOrgId,
+                OrgName = startStep.HandlerOrgName,
+                OrgAreaCode = startStep.HandlerOrgAreaCode,
+                OrgAreaName = startStep.HandlerOrgAreaName,
+                OrgLevel = 1
+            };
+
+            //StepDefine firstStepDefine
+            StepDefine firstStepDefine = workflow.WorkflowDefinition.FindStepDefine(startStep.NextStepCode);
+            //FlowAssignInfo flowAssignInfo
+            ////如果发起会签需检查是否支持发起会签
+            //var startStepDefine = workflow.WorkflowDefinition.FindStartStepDefine();
+
+            //下一节点是否为动态节点
+            var isNextDynamic = false;
+
+            FlowAssignInfo flowAssignInfo =
+                await _workflowApplication.GetNextStepFlowAssignInfoAsync(workflow, startStep, dto, firstStepDefine, isNextDynamic, HttpContext.RequestAborted);
+            //DateTime? expiredTime
+            DateTime? expiredTime = startStep.StepExpiredTime;
+
+            ///
+            await _mediator.Publish(
+                new StartWorkflowNotify(workflow, dto, flowAssignInfo, startStep.WorkflowTrace), HttpContext.RequestAborted);
+
+            //firstStep是否为end,t: 实际办理节点为startStep, 并且handlerId赋值 f: 实际办理节点为firstStep, handlerId未赋值
+            workflow.UpdateActualStepWhenHandle(startStep,
+                current.RequiredUserId, current.UserName,
+                current.RequiredOrgId, current.OrgName,
+                current.OrgAreaCode, current.OrgAreaName,
+                current.OrgLevel);
+
+            workflow.UpdateCurrentStepWhenHandle(startStep,
+                current.OrgAreaCode, current.OrgAreaName, current.OrgLevel);
+
+            var endTrace = await _workflowDomainService.EndAsync(workflow, dto, firstStepDefine,
+                startStep, current, expiredTime, HttpContext.RequestAborted);
+
+
+        }
+
+        _logger.LogInformation($"处理完成");
+    }
+
 }

+ 0 - 1
src/Hotline.Api/StartupExtensions.cs

@@ -188,7 +188,6 @@ internal static class StartupExtensions
             app.UseSwagger();
             app.UseSwaggerUI(c =>
             {
-                c.DocExpansion(DocExpansion.None);
                 //c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
             });
         }

+ 10 - 3
src/Hotline.Application/FlowEngine/IWorkflowApplication.cs

@@ -1,4 +1,5 @@
-using Hotline.FlowEngine.Definitions;
+using Hotline.FlowEngine;
+using Hotline.FlowEngine.Definitions;
 using Hotline.FlowEngine.WorkflowModules;
 using Hotline.FlowEngine.Workflows;
 using Hotline.Orders;
@@ -22,9 +23,15 @@ namespace Hotline.Application.FlowEngine
             CancellationToken cancellationToken = default);
 
         /// <summary>
-        /// 流转至下一节点(节点办理)
+        /// 查询下一节点办理对象类型(user or org)及实际办理对象
         /// </summary>
-        Task<Workflow> NextAsync(NextWorkflowDto dto, ISessionContext current, DateTime? expiredTime = null,
+		Task<FlowAssignInfo> GetNextStepFlowAssignInfoAsync(Workflow workflow, WorkflowStep currentStep,
+            BasicWorkflowDto dto, StepDefine nextStepDefine, bool isNextDynamic, CancellationToken cancellationToken);
+
+		/// <summary>
+		/// 流转至下一节点(节点办理)
+		/// </summary>
+		Task<Workflow> NextAsync(NextWorkflowDto dto, ISessionContext current, DateTime? expiredTime = null,
             CancellationToken cancellationToken = default);
 
         /// <summary>

+ 10 - 2
src/Hotline.Application/Handlers/FlowEngine/WorkflowEndHandler.cs

@@ -236,8 +236,16 @@ public class WorkflowEndHandler : INotificationHandler<EndWorkflowNotify>
                 //这里需要判断是否是警情退回
                 orderFlowDto.IsNonPoliceReturn = notification.Dto.External == null ? false : notification.Dto.External.IsPoliceReturn;
                 await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFiled, orderFlowDto, cancellationToken: cancellationToken);
-                //写入质检  针对受理之后直接结束的工单
-                await _qualityApplication.AddQualityAsync(EQualitySource.Accepted, order.Id, cancellationToken);
+
+                //try
+                //{
+                //    //写入质检  针对受理之后直接结束的工单
+                //    await _qualityApplication.AddQualityAsync(EQualitySource.Accepted, order.Id, cancellationToken);
+                //}
+                //catch (Exception e)
+                //{
+                //    _logger.LogError($"写入质检异常!orderId: {order.Id}, \r\n{e.Message}");
+                //}
 
                 //司法行政监督管理-工单处理
                 await _enforcementApplication.AddEnforcementOrderAsync(order, cancellationToken);

+ 11 - 3
src/Hotline.Application/Handlers/FlowEngine/WorkflowStartHandler.cs

@@ -196,12 +196,20 @@ namespace Hotline.Application.Handlers.FlowEngine
                             }
                         }
                     }
-                    catch
+                    catch(Exception e)
                     {
+                        _logger.LogError($"发送短信失败! orderId: {order.Id},\r\n{e.Message}");
                     }
 
-                    //写入质检
-                    await _qualityApplication.AddQualityAsync(EQualitySource.Accepted, order.Id, cancellationToken);
+                    try
+                    {
+                        //写入质检
+                        await _qualityApplication.AddQualityAsync(EQualitySource.Accepted, order.Id, cancellationToken);
+                    }
+                    catch (Exception e)
+                    {
+                        _logger.LogError($"写入质检异常!orderId: {order.Id}, \r\n{e.Message}");
+                    }
                     break;
                 case WorkflowModuleConsts.KnowledgeAdd:
                 case WorkflowModuleConsts.KnowledgeUpdate:

+ 15 - 9
src/Hotline.Application/JudicialManagement/EnforcementApplication.cs

@@ -266,9 +266,15 @@ namespace Hotline.Application.JudicialManagement
             return _judicialManagementOrdersRepository.Queryable()
                 .Where(d => d.IsItCounted == true)
                     .WhereIF(areaCode != "511500", d => d.AreaCode.StartsWith(areaCode))
-                    .WhereIF(dto.IsEnforcementOrder.HasValue, d => d.IsEnforcementOrder == dto.IsEnforcementOrder)//是否行政执法类
-                    .WhereIF(dto.IsPassTheBuckOrder.HasValue, d => d.IsPassTheBuckOrder == dto.IsPassTheBuckOrder)//是否推诿
-                     .WhereIF(dto.IsTheClueTrue.HasValue, d => d.IsTheClueTrue == dto.IsTheClueTrue)//线索是否属实
+                     // .WhereIF(dto.IsEnforcementOrder.HasValue, d => d.IsEnforcementOrder == dto.IsEnforcementOrder)//是否行政执法类
+                     //.WhereIF(dto.IsPassTheBuckOrder.HasValue, d => d.IsPassTheBuckOrder == dto.IsPassTheBuckOrder)//是否推诿
+                     //.WhereIF(dto.IsTheClueTrue.HasValue, d => d.IsTheClueTrue == dto.IsTheClueTrue)//线索是否属实
+                     .WhereIF(dto.IsTheClueTrueText == "1", d => d.IsTheClueTrue == null)//待核实
+                     .WhereIF(dto.IsTheClueTrueText == "2", d => d.IsTheClueTrue == true)//线索属实
+                     .WhereIF(dto.IsTheClueTrueText == "3", d => d.IsTheClueTrue == false)//线索不属实
+                     .WhereIF(dto.IsTheClueTrueText == "4", d => d.IsPassTheBuckOrder == true)//推诿工单
+                     .WhereIF(dto.IsTheClueTrueText == "5", d => d.IsEnforcementOrder == true)//行政执法类工单
+
                      .WhereIF(!string.IsNullOrEmpty(dto.EventTypeId), d => dto.EventTypeId == d.EventTypeId)//事项分类
                      .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title.Contains(dto.Title!)) //标题
                      .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No.Contains(dto.No)) //工单编码
@@ -303,7 +309,7 @@ namespace Hotline.Application.JudicialManagement
                 areCodeText = dto.AreaCode;
 
             return _judicialManagementOrdersRepository.Queryable()
-            .Where(d =>d.IsItCounted==true&& d.CreationTime >= dto.StartTime && d.CreationTime <= dto.EndTime && d.EventTypeId != null)
+            .Where(d => d.IsItCounted == true && d.CreationTime >= dto.StartTime && d.CreationTime <= dto.EndTime && d.EventTypeId != null)
             .WhereIF(!string.IsNullOrEmpty(dto.EventTypeId), d => d.EventTypeId.StartsWith(dto.EventTypeId))
             .WhereIF(!string.IsNullOrEmpty(areCodeText), d => d.AreaCode.StartsWith(areCodeText))
             .OrderByDescending(d => d.CreationTime)
@@ -320,7 +326,7 @@ namespace Hotline.Application.JudicialManagement
         {
             return _enforcementOrdersHandlerRepository.Queryable()
                    .LeftJoin<JudicialManagementOrders>((h, o) => h.OrderId == o.Id)
-                   .Where((h, o) => o.CreationTime >= StartTime && o.CreationTime <= EndTime&&o.IsItCounted==true)
+                   .Where((h, o) => o.CreationTime >= StartTime && o.CreationTime <= EndTime && o.IsItCounted == true)
                     .GroupBy((h, o) => new
                     {
                         OrgCode = h.OrgCode,
@@ -347,7 +353,7 @@ namespace Hotline.Application.JudicialManagement
         {
             return _enforcementOrdersHandlerRepository.Queryable()
                  .LeftJoin<JudicialManagementOrders>((x, o) => x.OrderId == o.Id)
-                 .Where((x, o) => o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime && o.Id != null&&o.IsItCounted==true)
+                 .Where((x, o) => o.CreationTime >= dto.StartTime && o.CreationTime <= dto.EndTime && o.Id != null && o.IsItCounted == true)
                  .WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.OrgCode == "001", (x, o) => x.OrgCode == dto.OrgCode)
                  .WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.OrgCode != "001", (x, o) => x.OrgCode.StartsWith(dto.OrgCode))
                  .WhereIF(dto.TheClueIsTrue == true, (x, o) => o.IsTheClueTrue == true)
@@ -398,7 +404,7 @@ namespace Hotline.Application.JudicialManagement
         {
             var areaCode = _sessionContext.OrgAreaCode ?? "511500";
             return _judicialManagementOrdersRepository.Queryable()
-                .Where(x => x.CreationTime >= StartTime && x.CreationTime <= EndTime&&x.IsItCounted==true)
+                .Where(x => x.CreationTime >= StartTime && x.CreationTime <= EndTime && x.IsItCounted == true)
                 .LeftJoin<SystemArea>((x, o) => x.AreaCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")) == o.Id)
                 .WhereIF(areaCode != "511500", (x, o) => x.AreaCode.StartsWith(areaCode))
                 .GroupBy((x, o) => new
@@ -452,7 +458,7 @@ namespace Hotline.Application.JudicialManagement
             return _judicialManagementOrdersRepository.Queryable()
                  .LeftJoin<OrderVisit>((x, o) => x.Id == o.OrderId)
                  .LeftJoin<OrderVisitDetail>((x, o, p) => o.Id == p.VisitId)
-                .Where((x, o, p) => o.VisitTime >= StartTime && o.VisitTime <= EndTime&&x.IsItCounted==true && p.VisitTarget == EVisitTarget.Org
+                .Where((x, o, p) => o.VisitTime >= StartTime && o.VisitTime <= EndTime && x.IsItCounted == true && p.VisitTarget == EVisitTarget.Org
                 && o.VisitState == EVisitState.Visited && !string.IsNullOrEmpty(p.VisitOrgCode) && x.OrderSoure == EOrderSoure.Hotline)
                 .GroupBy((x, o, p) => new
                 {
@@ -500,7 +506,7 @@ namespace Hotline.Application.JudicialManagement
             return _judicialManagementOrdersRepository.Queryable()
                 .LeftJoin<OrderVisit>((x, o) => x.Id == o.OrderId)
                 .LeftJoin<OrderVisitDetail>((x, o, p) => o.Id == p.VisitId)
-                .Where((x, o, p) => o.VisitTime >= dto.StartTime && o.VisitTime <= dto.EndTime&&x.IsItCounted==true && p.VisitTarget == EVisitTarget.Org && x.OrderSoure == EOrderSoure.Hotline)
+                .Where((x, o, p) => o.VisitTime >= dto.StartTime && o.VisitTime <= dto.EndTime && x.IsItCounted == true && p.VisitTarget == EVisitTarget.Org && x.OrderSoure == EOrderSoure.Hotline)
                 .Where((x, o, p) => o.VisitState == EVisitState.Visited && !string.IsNullOrEmpty(p.VisitOrgCode))
                 .WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.OrgCode == "001", (x, o, p) => p.VisitOrgCode == dto.OrgCode)
                 .WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.OrgCode != "001", (x, o, p) => p.VisitOrgCode.StartsWith(dto.OrgCode))

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

@@ -496,9 +496,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.StartsWith(dto.Keyword!)) //标题
             .WhereIF(!string.IsNullOrEmpty(dto.ProvinceNo), d => d.ProvinceNo == dto.ProvinceNo) //省本地编号
             .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No == dto.No) //工单编码
-            .WhereIF(!string.IsNullOrEmpty(dto.AcceptType), d => d.AcceptType == dto.AcceptType)//受理类型
+            .WhereIF(!string.IsNullOrEmpty(dto.AcceptType), d => d.AcceptTypeCode == dto.AcceptType)//受理类型
                                                                                                 //.WhereIF(dto.AcceptTypes.Any(), d => dto.AcceptTypes.Contains(d.AcceptTypeCode)) //受理类型
-            .WhereIF(!string.IsNullOrEmpty(dto.Channel), d => d.SourceChannel == dto.Channel)
+            .WhereIF(!string.IsNullOrEmpty(dto.Channel), d => d.SourceChannelCode == dto.Channel)
             //.WhereIF(dto.Channels.Any(), d => dto.Channels.Contains(d.SourceChannelCode)) //来源渠道
             //.WhereIF(dto.HotspotIds.Any(), d => dto.HotspotIds.Contains(d.HotspotId)) //热点类型
             .WhereIF(!string.IsNullOrEmpty(dto.Hotspot), d => d.HotspotSpliceName != null && d.HotspotSpliceName.Contains(dto.Hotspot))

+ 70 - 50
src/Hotline.Application/Quality/QualityApplication.cs

@@ -10,7 +10,12 @@ using Hotline.Share.Dtos.Quality;
 using Hotline.Share.Enums.Quality;
 using MapsterMapper;
 using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Options;
+using StackExchange.Redis;
+using System.Text.Encodings.Web;
+using System.Text.Json;
+using System.Text.Unicode;
 using XF.Domain.Authentications;
 using XF.Domain.Constants;
 using XF.Domain.Dependency;
@@ -30,6 +35,7 @@ namespace Hotline.Application.Quality
         //private readonly IRepository<TrCallRecord> _trCallRecordRepository;
         private readonly IRepository<QualityTemplate> _qualityTemplate;
         private readonly ISystemSettingCacheManager _systemSettingCacheManager;
+        private readonly ILogger<Hotline.Quality.Quality> _logger;
         private readonly ICallApplication _callApplication;
         private readonly IOptionsSnapshot<CallCenterConfiguration> _callcenterOptions;
 
@@ -41,10 +47,11 @@ namespace Hotline.Application.Quality
             IAiQualityService aiQualityService,
             //IRepository<TrCallRecord> trCallRecordRepository,
             IRepository<QualityTemplate> qualityTemplate,
-			IOrderRepository orderRepository,
+            IOrderRepository orderRepository,
             ISystemSettingCacheManager systemSettingCacheManager,
             ICallApplication callApplication,
-            IOptionsSnapshot<CallCenterConfiguration> callcenterOptions)
+            IOptionsSnapshot<CallCenterConfiguration> callcenterOptions,
+            ILogger<Hotline.Quality.Quality> logger)
         {
             _sessionContext = sessionContext;
             _mapper = mapper;
@@ -53,10 +60,12 @@ namespace Hotline.Application.Quality
             _aiQualityService = aiQualityService;
             //_trCallRecordRepository = trCallRecordRepository;
             _qualityTemplate = qualityTemplate;
-			_orderRepository = orderRepository;
+            _orderRepository = orderRepository;
             _systemSettingCacheManager = systemSettingCacheManager;
             _callApplication = callApplication;
             _callcenterOptions = callcenterOptions;
+            _logger = logger;
+
         }
 
         public async Task AddQualityAsync(EQualitySource Source, string OrderId, string VisitId, CancellationToken cancellationToken)
@@ -73,7 +82,7 @@ namespace Hotline.Application.Quality
             else
             {
                 if (Source == EQualitySource.Visit) await _qualityRepository.Updateable().SetColumns(x => x.VisitId == VisitId).Where(x => x.OrderId == OrderId && x.Source == Source).ExecuteCommandAsync();
-			}
+            }
         }
 
         public async Task AddQualityAsync(EQualitySource Source, string OrderId, CancellationToken cancellationToken)
@@ -92,7 +101,7 @@ namespace Hotline.Application.Quality
         {
             var quality = _mapper.Map<Hotline.Quality.Quality>(model);
             quality.InitId();
-			
+
             if (model.QualityDetails.Any())
             {
                 foreach (var item in model.QualityDetails)
@@ -102,54 +111,65 @@ namespace Hotline.Application.Quality
                 List<QualityDetail> details = _mapper.Map<List<QualityDetail>>(model.QualityDetails);
                 await _qualiteyDetail.AddRangeAsync(details, cancellationToken);
             }
-            //受理智能质检
-            if (model.Source == EQualitySource.Accepted)
+            var order = await _orderRepository.GetAsync(model.OrderId);
+			//受理智能质检
+			if (model.Source == EQualitySource.Accepted)
             {
-	            var teAny = await _qualityTemplate.Queryable()
-		            .LeftJoin<QualityTemplateDetail>((x, d) => x.Id == d.TemplateId)
-		            .LeftJoin<QualityItem>((x, d, i) => d.ItemId == i.Id)
-		            .Where((x, d, i) => i.IsIntelligent == 1).AnyAsync();
-	            if (teAny)
-	            {
-		            var order = await _orderRepository.GetAsync(model.OrderId);
-		            if (order != null && !string.IsNullOrEmpty(order.CallId))
-		            {
-			            quality.AiQuality = true;
-			            quality.Mode = "智能质检";
-			            //var call = await _trCallRecordRepository.GetAsync(x => x.CallAccept == order.CallId); //由CallAccept改成OtherAccept
-			            //var call = await _trCallRecordRepository.GetAsync(x => x.OtherAccept == order.CallId);
-
-                        var audioFile = string.Empty;
-                        var fromNo = string.Empty;
-                        DateTime? callStartTime = null;
-                        if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.TianRun)
-                        {
-                            var call = await _callApplication.GetTianrunCallAsync(order.CallId, cancellationToken);
-                            audioFile = call.RecordingAbsolutePath;
-                            fromNo = call.CPN;
-                            callStartTime = call.CreatedTime;
-                        }
-                        else if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.XingTang)
-                        {
-                            var call = await _callApplication.GetCallAsync(order.CallId, cancellationToken);
-                            audioFile = call.AudioFile;
-                            fromNo = call.FromNo;
-                            callStartTime = call.BeginIvrTime;
-                        }
-
-                        var setting = _systemSettingCacheManager.GetSetting(SettingConstants.ViteRecordPrefix);
-						//await _aiQualityService.CreateAiOrderQualityTask(quality, call, order, setting?.SettingValue[0], cancellationToken);
-                        await _aiQualityService.CreateAiOrderQualityTask(
-                            quality,
-                            audioFile,
-                            fromNo,
-                            callStartTime,
-                            order, setting?.SettingValue[0], cancellationToken);
+                var teAny = await _qualityTemplate.Queryable()
+                    .LeftJoin<QualityTemplateDetail>((x, d) => x.Id == d.TemplateId)
+                    .LeftJoin<QualityItem>((x, d, i) => d.ItemId == i.Id)
+                    .Where((x, d, i) => i.IsIntelligent == 1).AnyAsync();
+                if (teAny)
+                {
+                    if (order != null && !string.IsNullOrEmpty(order.CallId))
+                    {
+                        quality.AiQuality = true;
+                        quality.Mode = "智能质检";
                     }
-	            }
+                }
             }
-			await _qualityRepository.AddAsync(quality, cancellationToken);
-		}
+            await _qualityRepository.AddAsync(quality, cancellationToken);
+   //         ///调用智能质检 捷通
+			//if (quality.AiQuality is true)
+   //         {
+			//	try
+			//	{
+			//		var audioFile = string.Empty;
+			//		var fromNo = string.Empty;
+			//		DateTime? callStartTime = null;
+			//		if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.TianRun)
+			//		{
+			//			var call = await _callApplication.GetTianrunCallAsync(order.CallId, cancellationToken);
+			//			audioFile = call.RecordingAbsolutePath;
+			//			fromNo = call.CPN;
+			//			callStartTime = call.CreatedTime;
+			//		}
+			//		else if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.XingTang)
+			//		{
+			//			var call = await _callApplication.GetCallAsync(order.CallId, cancellationToken);
+			//			audioFile = call.AudioFile;
+			//			fromNo = call.FromNo;
+			//			callStartTime = call.BeginIvrTime;
+			//		}
+
+			//		var setting = _systemSettingCacheManager.GetSetting(SettingConstants.ViteRecordPrefix);
+			//		_aiQualityService.CreateAiOrderQualityTask(
+			//			quality,
+			//			audioFile,
+			//			fromNo,
+			//		callStartTime,
+			//			order, setting?.SettingValue[0], cancellationToken);
+			//	}
+			//	catch (Exception e)
+			//	{
+			//		_logger.LogError($"写入智能质检异常!, \r\n{e.Message}");
+			//	}
+			//}
+
+            //_logger.LogInformation($"质检对象:{System.Text.Json.JsonSerializer.Serialize(quality, 
+            //    new JsonSerializerOptions { Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.CjkUnifiedIdeographs) })}");
+            //await _qualityRepository.AddAsync(quality, cancellationToken);
+        }
 
         public async Task UpdateQualityAsync(UpdateQualityDto model, CancellationToken cancellationToken)
         {

+ 9 - 6
src/Hotline.Repository.SqlSugar/Extensions/SqlSugarStartupExtensions.cs

@@ -207,16 +207,19 @@ 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)));
+                //获取原生SQL推荐 5.1.4.63  性能OK
+                //Log.Information(UtilMethods.GetNativeSql(sql, pars));
+
+                //Log.Information("Sql: {0}", sql);
+                //Log.Information("SqlParameters: {0}", string.Join(',', pars.Select(d => d.Value)));
             };
             db.Aop.OnError = (exp) =>//SQL报错
             {
-                //exp.sql 这样可以拿到错误SQL,性能无影响拿到ORM带参数使用的SQL
-                Log.Error("SqlError: {0}", exp.Sql);
-
+                //获取原生SQL推荐 5.1.4.63  性能OK
+                Log.Error(UtilMethods.GetNativeSql(exp.Sql, (SugarParameter[])exp.Parametres));
+                Log.Error(exp.InnerException.Message);
                 //5.0.8.2 获取无参数化 SQL  对性能有影响,特别大的SQL参数多的,调试使用
-                //UtilMethods.GetSqlString(DbType.SqlServer,exp.sql,exp.parameters)           
+                //UtilMethods.GetSqlString(DbType.SqlServer, exp.sql, exp.parameters)
             };
             //db.Aop.OnExecutingChangeSql = (sql, pars) => //可以修改SQL和参数的值
             //{

+ 21 - 0
src/Hotline.Share/Dtos/JudicialManagement/EnforcementOrderListDto.cs

@@ -152,6 +152,27 @@ namespace Hotline.Share.Dtos.JudicialManagement
         /// </summary>
         public string? AcceptorOrgName { get; set; }
 
+        /// <summary>
+        /// 执法部门
+        /// </summary>
+        public List<Kv> EnforcementOrdersHandler { get; set; }
+        public string EnforcementOrdersHandlerText => GetText();
+
+        public string GetText()
+        {
+            string strOrgName = "";
+            if (EnforcementOrdersHandler != null && EnforcementOrdersHandler.Count > 0)
+            {
+                foreach (var item in EnforcementOrdersHandler)
+                {
+                    strOrgName += item.Key + ",";
+                }
+                if (!string.IsNullOrEmpty(strOrgName))
+                    strOrgName = strOrgName.Substring(0, strOrgName.Length - 1);
+            }
+            return strOrgName;
+        }
+
         /// <summary>
         /// 转换是否文本
         /// </summary>

+ 14 - 0
src/Hotline.Share/Dtos/JudicialManagement/JudicialManagementAddOrderDto.cs

@@ -187,5 +187,19 @@ namespace Hotline.Share.Dtos.JudicialManagement
         /// 创建时间
         /// </summary>
         public DateTime CreationTime { get; set; }
+
+        /// <summary>
+        /// 省市区
+        /// </summary>
+        public string IncidentAddressText => IncidentAddress();
+
+        /// <summary>
+        /// 组装省市区
+        /// </summary>
+        /// <returns></returns>
+        public string IncidentAddress()
+        {
+            return $"{Province}{City}{County}{Town}";
+        }
     }
 }

+ 5 - 0
src/Hotline.Share/Dtos/JudicialManagement/QueryEnforcementOrderDto.cs

@@ -232,5 +232,10 @@ namespace Hotline.Share.Dtos.JudicialManagement
         /// 线索是否属实
         /// </summary>
         public bool? IsTheClueTrue { get; set; }
+
+        /// <summary>
+        /// 线索是否属实0:全部,1:待核实,2:线索属实,3:线索不属实,4:推诿工单,5:行政执法类工单
+        /// </summary>
+        public string IsTheClueTrueText {  get; set; }
     }
 }

+ 4 - 2
src/Hotline/Authentications/ProvinceSessionContext.cs

@@ -13,17 +13,19 @@ namespace Hotline.Authentications
             OrgLevel = 1;
         }
 
+        //TODO 取消写入
         /// <summary>
         /// Id of current tenant or null for host
         /// </summary>
-        public string? UserId { get; }
+        public string? UserId { get; set; }
 
         /// <summary>
         /// Id of current user or throw Exception for guest
         /// </summary>
         /// <exception cref="AuthenticationException"></exception>
         public string RequiredUserId => UserId ?? throw new ArgumentNullException();
-        public string? UserName { get; }
+        //TODO 取消写入
+		public string? UserName { get; set; }
         public string? Phone { get; }
 
         /// <summary>

+ 1 - 1
src/Hotline/Caching/Services/SysDicDataCacheManager.cs

@@ -21,7 +21,7 @@ namespace Hotline.Caching.Services
         {
             var sysDicDataList = _cacheSysDicData.GetOrSet(code, k =>
             {
-                return _sysDicDataRepository.Queryable().Where(x => x.DicTypeCode == code).OrderBy(x=>x.Sort).ToTreeAsync(x => x.Children, it => it.ParentId, "").GetAwaiter().GetResult();
+                return _sysDicDataRepository.Queryable().Where(x => x.DicTypeCode == code && x.IsShow == true).OrderBy(x=>x.Sort).ToTreeAsync(x => x.Children, it => it.ParentId, "").GetAwaiter().GetResult();
             });
             return sysDicDataList;
         }

+ 11 - 4
src/Hotline/Settings/SystemDicData.cs

@@ -5,8 +5,8 @@ using XF.Domain.Repository;
 namespace Hotline.Settings
 {
     [Description("字典表")]
-    public class SystemDicData: CreationEntity
-    {
+    public class SystemDicData : FullStateEntity
+	{
         /// <summary>
         /// 字典类型Id
         /// </summary>
@@ -32,10 +32,17 @@ namespace Hotline.Settings
         /// </summary>
         [SugarColumn(DefaultValue = "0")]
         public int Sort { get; set; }
+
         /// <summary>
-        /// 上级ID
+        /// 是否显示
         /// </summary>
-        [SugarColumn(IsNullable = true)]
+        [SugarColumn(DefaultValue = "t")]
+		public bool IsShow { get; set; }
+
+		/// <summary>
+		/// 上级ID
+		/// </summary>
+		[SugarColumn(IsNullable = true)]
         public string? ParentId { get; set; }
 
         [SugarColumn(IsIgnore = true)]