Browse Source

Merge branch 'test' into lib/test

libin 2 months ago
parent
commit
7974973986
34 changed files with 434 additions and 386 deletions
  1. 76 73
      src/Hotline.Api/Controllers/Bi/BiOrderController.cs
  2. 2 2
      src/Hotline.Api/Controllers/KnowledgeController.cs
  3. 46 10
      src/Hotline.Api/Controllers/OrderController.cs
  4. 0 1
      src/Hotline.Application/FlowEngine/WorkflowApplication.cs
  5. 5 84
      src/Hotline.Application/Handlers/FlowEngine/WorkflowEndHandler.cs
  6. 6 20
      src/Hotline.Application/Orders/OrderApplication.cs
  7. 1 1
      src/Hotline.Application/Snapshot/IInviteCodeApplication.cs
  8. 2 2
      src/Hotline.Application/Snapshot/InviteCodeApplication.cs
  9. 9 6
      src/Hotline.Application/StatisticalReport/IOrderReportApplication.cs
  10. 87 6
      src/Hotline.Application/StatisticalReport/OrderReportApplication.cs
  11. 8 1
      src/Hotline.Repository.SqlSugar/BaseRepository.cs
  12. 14 6
      src/Hotline.Repository.SqlSugar/Orders/OrderRepository.cs
  13. 6 1
      src/Hotline.Share/Dtos/Bi/BiOrderDto.cs
  14. 1 1
      src/Hotline.Share/Dtos/Order/OrderBiDto.cs
  15. 6 1
      src/Hotline.Share/Requests/PagedKeywordRequest.cs
  16. 1 10
      src/Hotline/Orders/IOrderDomainService.cs
  17. 2 1
      src/Hotline/Orders/IOrderRepository.cs
  18. 0 130
      src/Hotline/Orders/OrderDomainService.cs
  19. 3 1
      test/Hotline.Tests/Application/DefaultCallApplicationTest.cs
  20. 3 1
      test/Hotline.Tests/Application/IndustryApplicationTest.cs
  21. 28 2
      test/Hotline.Tests/Application/InviteCodeApplicationTest.cs
  22. 11 2
      test/Hotline.Tests/Application/KnowApplicationTest.cs
  23. 46 10
      test/Hotline.Tests/Application/OrderSnapshotApplicationTest.cs
  24. 9 1
      test/Hotline.Tests/Application/RedPackApplicationTest.cs
  25. 4 1
      test/Hotline.Tests/Application/SnapshotApplicationTest.cs
  26. 7 1
      test/Hotline.Tests/Application/SystemSettingCacheManagerTest.cs
  27. 8 1
      test/Hotline.Tests/Controller/IndustryControllerTest.cs
  28. 10 1
      test/Hotline.Tests/Controller/KnowledgeControllerTest.cs
  29. 10 2
      test/Hotline.Tests/Controller/OrderControllerTest.cs
  30. 8 1
      test/Hotline.Tests/Controller/SnapshotControllerTest.cs
  31. 2 1
      test/Hotline.Tests/Domain/OrderVisitDomainServiceTest.cs
  32. 1 0
      test/Hotline.Tests/SqlSuger/CapDbExtensions.cs
  33. 11 4
      test/Hotline.Tests/TestBase.cs
  34. 1 1
      test/Hotline.Tests/appsettings.Development.json

+ 76 - 73
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -49,6 +49,7 @@ using Hotline.File;
 using Hotline.KnowledgeBase;
 using Hotline.KnowledgeBase;
 using DocumentFormat.OpenXml.Vml.Spreadsheet;
 using DocumentFormat.OpenXml.Vml.Spreadsheet;
 using Hotline.Share.Tools;
 using Hotline.Share.Tools;
+using MediatR;
 
 
 namespace Hotline.Api.Controllers.Bi
 namespace Hotline.Api.Controllers.Bi
 {
 {
@@ -1147,79 +1148,81 @@ namespace Hotline.Api.Controllers.Bi
         public async Task<object> HotPortJoinOrgStatistics([FromQuery] HotPortJoinOrgStatisticsRequest dto)
         public async Task<object> HotPortJoinOrgStatistics([FromQuery] HotPortJoinOrgStatisticsRequest dto)
         {
         {
             var IsCenter = _sessionContext.OrgIsCenter;
             var IsCenter = _sessionContext.OrgIsCenter;
-            return await _orderRepository.HotPortJoinOrgStatistics(dto.StartTime, dto.EndTime, IsCenter, _sessionContext.OrgId);
-        }
-
-
-		/// <summary>
-		/// 热点类型部门统计--导出
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		//[HttpPost("hotport-org-statistics/export")]
-		//public async Task<FileStreamResult> ExportHotPortJoinOrgStatistics([FromBody] ExportHotPortJoinOrgStatisticsRequest dto)
-		//{
-		//	if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
-		//	if (dto.AddColumnName is null || dto.AddColumnName.Count == 0) throw UserFriendlyException.SameMessage("导出字段不能为空");
-		//	if (dto.AddColumnName.FirstOrDefault() != "部门名称") throw UserFriendlyException.SameMessage("导出字段第一个必须是'部门名称'");
-
-		//	var (dissatisfiedReason, list) = await _orderRepository.HotPortJoinOrgStatistics(dto, _sessionContext.OrgIsCenter);
-		//	var dataTable = await _orderReportApplication.ExportQueryVisitNoSatisfiedAsync(dissatisfiedReason, list, dto.AddColumnName);
-
-		//	return ExcelStreamResult(ExcelHelper.CreateStream(dataTable), "回访不满意原因统计");
-		//}
-
-		/// <summary>
-		/// 热点类型部门统计
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpGet("hotport-org-statistics-detail")]
-		public async Task<PagedDto<OrderDto>> HotPortJoinOrgStatisticsDetail([FromQuery] HotPortJoinOrgStatisticsRequestDetail dto)
-		{
-			var (total, items) = await _orderRepository.HotPortJoinOrgStatisticsDetail(dto)
-				.ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
-			return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
-		}
-
-		/// <summary>
-		/// 热点类型部门统计明细导出
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpPost("hotport-org-statistics-detail/export")]
-		public async Task<FileStreamResult> HotPortJoinOrgStatisticsDetailExport([FromBody] ExportExcelDto<HotPortJoinOrgStatisticsRequestDetail> dto)
-		{
-			var query = _orderRepository.HotPortJoinOrgStatisticsDetail(dto.QueryDto);
-			List<Order> data;
-			if (dto.IsExportAll)
-			{
-				data = await query.ToListAsync(HttpContext.RequestAborted);
-			}
-			else
-			{
-				var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
-				data = items;
-			}
-			var orderDtos = _mapper.Map<IReadOnlyList<OrderDto>>(data);
-			dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
-
-			var dtos = orderDtos
-				.Select(stu => _mapper.Map(stu, typeof(OrderDto), dynamicClass))
-				.Cast<object>()
-				.ToList();
-
-			var stream = ExcelHelper.CreateStream(dtos);
-
-			return ExcelStreamResult(stream, "热点类型部门统计明细");
-		}
-
-		/// <summary>
-		/// 回访量统计导出
-		/// </summary>
-		/// <param name="dto"></param>
-		/// <returns></returns>
-		[HttpPost("visit-measure-statistics-export")]
+            var (hotSpot, data) = await _orderRepository.HotPortJoinOrgStatistics(dto.StartTime, dto.EndTime, IsCenter, _sessionContext.OrgId);
+			return  new { hotSpot, data };
+        }
+
+
+        /// <summary>
+        /// 热点类型部门统计--导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("hotport-org-statistics/export")]
+        public async Task<FileStreamResult> ExportHotPortJoinOrgStatistics([FromBody] ExportHotPortJoinOrgStatisticsRequest dto)
+        {
+            if (!dto.StartTime.HasValue || !dto.EndTime.HasValue) throw UserFriendlyException.SameMessage("请选择时间!");
+            if (dto.AddColumnName is null || dto.AddColumnName.Count == 0) throw UserFriendlyException.SameMessage("导出字段不能为空");
+            if (dto.AddColumnName.FirstOrDefault() != "部门名称") throw UserFriendlyException.SameMessage("导出字段第一个必须是'部门名称'");
+            var IsCenter = _sessionContext.OrgIsCenter;
+
+            var (hotSpot, list) = await _orderRepository.HotPortJoinOrgStatistics(dto.StartTime.Value, dto.EndTime.Value, IsCenter, _sessionContext.OrgId);
+            var dataTable = await _orderReportApplication.ExportHotPortJoinOrgStatisticsAsync(hotSpot, list, dto.AddColumnName);
+
+            return ExcelStreamResult(ExcelHelper.CreateStream(dataTable), "热点类型部门统计");
+        }
+
+        /// <summary>
+        /// 热点类型部门统计明细
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpGet("hotport-org-statistics/detail")]
+        public async Task<PagedDto<OrderDto>> HotPortJoinOrgStatisticsDetail([FromQuery] HotPortJoinOrgStatisticsRequestDetail dto)
+        {
+            var (total, items) = await _orderRepository.HotPortJoinOrgStatisticsDetail(dto)
+                .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
+            return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
+        }
+
+        /// <summary>
+        /// 热点类型部门统计明细导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("hotport-org-statistics/detail/export")]
+        public async Task<FileStreamResult> HotPortJoinOrgStatisticsDetailExport([FromBody] ExportExcelDto<HotPortJoinOrgStatisticsRequestDetail> dto)
+        {
+            var query = _orderRepository.HotPortJoinOrgStatisticsDetail(dto.QueryDto);
+            List<Order> data;
+            if (dto.IsExportAll)
+            {
+                data = await query.ToListAsync(HttpContext.RequestAborted);
+            }
+            else
+            {
+                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+                data = items;
+            }
+            var orderDtos = _mapper.Map<IReadOnlyList<OrderDto>>(data);
+            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+            var dtos = orderDtos
+                .Select(stu => _mapper.Map(stu, typeof(OrderDto), dynamicClass))
+                .Cast<object>()
+                .ToList();
+
+            var stream = ExcelHelper.CreateStream(dtos);
+
+            return ExcelStreamResult(stream, "热点类型部门统计明细");
+        }
+
+        /// <summary>
+        /// 回访量统计导出
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("visit-measure-statistics-export")]
         [AllowAnonymous]
         [AllowAnonymous]
         public async Task<FileStreamResult> VisitMeasureStatisticsExport([FromBody] ExportExcelDto<VisitMeasureStatisticsRequest> dto)
         public async Task<FileStreamResult> VisitMeasureStatisticsExport([FromBody] ExportExcelDto<VisitMeasureStatisticsRequest> dto)
         {
         {

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

@@ -547,7 +547,7 @@ namespace Hotline.Api.Controllers
             var knowledge = await _knowledgeRepository.GetAsync(dto.Data.Id, HttpContext.RequestAborted);
             var knowledge = await _knowledgeRepository.GetAsync(dto.Data.Id, HttpContext.RequestAborted);
             if (knowledge == null)
             if (knowledge == null)
                 throw UserFriendlyException.SameMessage("无效知识库数据");
                 throw UserFriendlyException.SameMessage("无效知识库数据");
-            if (knowledge.Status == EKnowledgeStatus.OnShelf || knowledge.Status == EKnowledgeStatus.Auditing)
+            if ((knowledge.Status == EKnowledgeStatus.OnShelf  && knowledge.ExpiredTime >= DateTime.Now) || knowledge.Status == EKnowledgeStatus.Auditing)
                 throw UserFriendlyException.SameMessage("知识库数据不可删除");
                 throw UserFriendlyException.SameMessage("知识库数据不可删除");
             if (knowledge.Status == EKnowledgeStatus.Drafts || knowledge.Status == EKnowledgeStatus.Revert)
             if (knowledge.Status == EKnowledgeStatus.Drafts || knowledge.Status == EKnowledgeStatus.Revert)
             {
             {
@@ -573,7 +573,7 @@ namespace Hotline.Api.Controllers
             var knowledge = await _knowledgeRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
             var knowledge = await _knowledgeRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
             if (knowledge == null)
             if (knowledge == null)
                 throw UserFriendlyException.SameMessage("无效知识库数据");
                 throw UserFriendlyException.SameMessage("无效知识库数据");
-            if (knowledge.Status == EKnowledgeStatus.OnShelf || knowledge.Status == EKnowledgeStatus.Auditing)
+            if ((knowledge.Status == EKnowledgeStatus.OnShelf && knowledge.ExpiredTime >= DateTime.Now) || knowledge.Status == EKnowledgeStatus.Auditing)
                 throw UserFriendlyException.SameMessage("知识库数据不可删除");
                 throw UserFriendlyException.SameMessage("知识库数据不可删除");
 
 
             if (knowledge.Status == EKnowledgeStatus.Drafts || knowledge.Status == EKnowledgeStatus.Revert)
             if (knowledge.Status == EKnowledgeStatus.Drafts || knowledge.Status == EKnowledgeStatus.Revert)

+ 46 - 10
src/Hotline.Api/Controllers/OrderController.cs

@@ -2830,12 +2830,47 @@ public class OrderController : BaseController
         return rspModel;
         return rspModel;
     }
     }
 
 
-    /// <summary>
-    /// 更新甄别提起截至时限
-    /// </summary>
-    /// <param name="dto"></param>
-    /// <returns></returns>
-    [HttpPut("order_screen_endtime")]
+	/// <summary>
+	/// 甄别详情
+	/// </summary>
+	/// <param name="id"></param>
+	/// <returns></returns>
+	[HttpGet("screen/visitdetail/{id}")]
+	public async Task<OrderScreenListDto> VisitDetailScreenEntity(string id)
+	{
+		var model = await _orderScreenRepository.Queryable(canView: false)
+			.Includes(x => x.Order)
+			.Includes(x => x.Workflow, d => d.Steps)
+			.Includes(x => x.Visit, d => d.Order)
+			.FirstAsync(x => x.VisitDetailId  == id);
+		var rspModel = _mapper.Map<OrderScreenListDto>(model);
+		//rspModel.IsCanHandle = model.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
+		rspModel.IsCanHandle = model.Workflow?.IsCanHandle(
+			_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, _sessionContext.Roles) ?? false;
+		if (model.Status == EScreenStatus.SendBack && model.SendBackApply)
+			rspModel.IsCanHandle = false;
+		rspModel.Handle = false;
+		if (!string.IsNullOrEmpty(rspModel.WorkflowId))
+		{
+			rspModel.Handle = await _workflowDomainService.CheckCurrentIsStartStepAsync(rspModel.WorkflowId, _sessionContext.RequiredUserId,
+				_sessionContext.RequiredOrgId, HttpContext.RequestAborted);
+		}
+
+		if (rspModel.FileJson != null && rspModel.FileJson.Any())
+		{
+			var ids = rspModel.FileJson.Select(x => x.Id).ToList();
+			rspModel.Files = await _fileRepository.GetFilesAsync(ids, HttpContext.RequestAborted);
+		}
+
+		return rspModel;
+	}
+
+	/// <summary>
+	/// 更新甄别提起截至时限
+	/// </summary>
+	/// <param name="dto"></param>
+	/// <returns></returns>
+	[HttpPut("order_screen_endtime")]
     [LogFilter("更新甄别提起截至时限")]
     [LogFilter("更新甄别提起截至时限")]
     public async Task Update([FromBody] OrderScreenEndTimeDto dto)
     public async Task Update([FromBody] OrderScreenEndTimeDto dto)
     {
     {
@@ -5855,7 +5890,7 @@ public class OrderController : BaseController
                 NextStepCode = dto.NextStepCode,
                 NextStepCode = dto.NextStepCode,
                 NextStepName = dto.NextStepName,
                 NextStepName = dto.NextStepName,
                 NextHandlers = dto.NextHandlers,
                 NextHandlers = dto.NextHandlers,
-                Opinion = dto.Cause,
+                Opinion = "【特提理由】" + dto.Cause,
                 FlowDirection = dto.FlowDirection,
                 FlowDirection = dto.FlowDirection,
                 HandlerType = dto.HandlerType,
                 HandlerType = dto.HandlerType,
                 BusinessType = dto.BusinessType
                 BusinessType = dto.BusinessType
@@ -6087,7 +6122,7 @@ public class OrderController : BaseController
                 NextStepCode = dto.NextStepCode,
                 NextStepCode = dto.NextStepCode,
                 NextStepName = dto.NextStepName,
                 NextStepName = dto.NextStepName,
                 NextHandlers = dto.NextHandlers,
                 NextHandlers = dto.NextHandlers,
-                Opinion = dto.Reason,
+                Opinion = "【特提理由】" + dto.Reason,
                 FlowDirection = dto.FlowDirection,
                 FlowDirection = dto.FlowDirection,
                 HandlerType = dto.HandlerType,
                 HandlerType = dto.HandlerType,
                 BusinessType = dto.BusinessType,
                 BusinessType = dto.BusinessType,
@@ -6458,7 +6493,7 @@ public class OrderController : BaseController
                     NextStepCode = special.NextStepCode,
                     NextStepCode = special.NextStepCode,
                     NextStepName = special.NextStepName,
                     NextStepName = special.NextStepName,
                     NextHandlers = special.NextHandlers,
                     NextHandlers = special.NextHandlers,
-                    Opinion = dto.Opinion,
+                    Opinion = "【特提理由】" + dto.Opinion,
                     FlowDirection = special.FlowDirection,
                     FlowDirection = special.FlowDirection,
                     HandlerType = special.HandlerType.Value,
                     HandlerType = special.HandlerType.Value,
                     BusinessType = special.BusinessType.Value
                     BusinessType = special.BusinessType.Value
@@ -6870,7 +6905,8 @@ public class OrderController : BaseController
 
 
             if (!order.FileOrgIsCenter.Value)
             if (!order.FileOrgIsCenter.Value)
             {
             {
-                if (step.Steps.Where(x => x.BusinessType == EBusinessType.Department && x.OrgLevel == 1).Any())
+				 //&& x.StepType == EStepType.Normal
+				if (step.Steps.Where(x => x.BusinessType == EBusinessType.Department && x.OrgLevel == 1).Any())
                 {
                 {
                     var stepdDefault = step.Steps.Where(x => x.BusinessType == EBusinessType.Department && x.OrgLevel == 1)
                     var stepdDefault = step.Steps.Where(x => x.BusinessType == EBusinessType.Department && x.OrgLevel == 1)
                         .FirstOrDefault();
                         .FirstOrDefault();

+ 0 - 1
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -16,7 +16,6 @@ using Hotline.File;
 using Hotline.Share.Enums.Settings;
 using Hotline.Share.Enums.Settings;
 using XF.Domain.Authentications;
 using XF.Domain.Authentications;
 using XF.Domain.Dependency;
 using XF.Domain.Dependency;
-using XF.Domain.Entities;
 using XF.Domain.Exceptions;
 using XF.Domain.Exceptions;
 using XF.Domain.Extensions;
 using XF.Domain.Extensions;
 using XF.Domain.Repository;
 using XF.Domain.Repository;

+ 5 - 84
src/Hotline.Application/Handlers/FlowEngine/WorkflowEndHandler.cs

@@ -324,100 +324,21 @@ public class WorkflowEndHandler : INotificationHandler<EndWorkflowNotify>
                     //推诿工单
                     //推诿工单
                     // await _enforcementApplication.AddPassTheBuckOrderAsync(order, _sessionContext.OrgId, _sessionContext.OrgName, cancellationToken);
                     // await _enforcementApplication.AddPassTheBuckOrderAsync(order, _sessionContext.OrgId, _sessionContext.OrgName, cancellationToken);
                     break;
                     break;
-                //case WorkflowModuleConsts.OrderScreen:
-                //    var screen = await _orderScreenRepository.GetAsync(workflow.ExternalId, cancellationToken);
-                //    if (screen != null)
-                //    {
-                //        screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
-                //        if (isReviewPass)
-                //        {
-                //            screen.Status = EScreenStatus.End;
-                //            screen.ReplyContent = workflow.ActualOpinion;
-                //            await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
-                //            var visitDetail =
-                //                await _orderVisitedDetailRepository.GetAsync(screen.VisitDetailId, cancellationToken);
-                //            if (visitDetail != null)
-                //            {
-                //                var screenSatisfy = new Kv() { Key = "-1", Value = "视为满意" };
-                //                visitDetail.OrgProcessingResults = screenSatisfy;
-                //                //visitDetail.OrgHandledAttitude = screenSatisfy;
-                //                await _orderVisitedDetailRepository.UpdateAsync(visitDetail, cancellationToken);
-                //                // 修改主表当前评价结果
-                //                await _orderVisitRepository.Updateable().SetColumns(v => new OrderVisit() { NowEvaluate = screenSatisfy }).Where(v => v.Id == visitDetail.VisitId).ExecuteCommandAsync(cancellationToken);
-                //                //获取回访信息
-                //                var visit = await _orderVisitRepository.Queryable().Includes(x => x.Order)
-                //                    .Includes(x => x.OrderVisitDetails)
-                //                    .Where(x => x.Id == screen.VisitId).FirstAsync(cancellationToken);
-                //                if (visit != null)
-                //                {
-                //                    //获取回访明细
-                //                    var visitDe = visit.OrderVisitDetails.First(x => x.Id == screen.VisitDetailId);
-                //                    //推省上
-                //                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderScreenApplyed,
-                //                          new PublishVisitDto()
-                //                          {
-                //                              Order = _mapper.Map<OrderDto>(visit.Order),
-                //                              No = visit.No,
-                //                              VisitType = visit.VisitType,
-                //                              VisitName = visit.CreatorName,
-                //                              VisitTime = visit.VisitTime,
-                //                              VisitRemark = string.IsNullOrEmpty(visitDe.VisitContent) ? screenSatisfy.Value : visitDe.VisitContent,
-                //                              AreaCode = visit.Order.AreaCode!,
-                //                              SubjectResultSatifyCode = visitDe.OrgProcessingResults?.Key,
-                //                              FirstSatisfactionCode = visit.Order.FirstVisitResultCode!,
-                //                              ClientGuid = ""
-                //                          });
-
-                //                    //推门户
-                //                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisitedWeb, new PublishVisitAllDto()
-                //                    {
-                //                        Id = visit.Id,
-                //                        Order = _mapper.Map<OrderDto>(visit.Order),
-                //                        OrderVisitDetails = _mapper.Map<List<VisitDetailDto>>(visit.OrderVisitDetails),
-                //                        VisitName = visit.CreatorName,
-                //                        VisitTime = visit.VisitTime,
-                //                        VisitType = visit.VisitType,
-                //                        VisitState = visit.VisitState,
-                //                        PublishTime = visit.PublishTime,
-                //                    }, cancellationToken: cancellationToken);
-                //                }
-                //            }
-                //        }
-                //      else
-                //               {
-                //                   await _orderRepository.OrderScreenRevisionVisit(screen.VisitId, true, cancellationToken);
-                //                   screen.Status = EScreenStatus.Refuse;
-                //                   screen.ReplyContent = workflow.ActualOpinion;
-                //               }
-                //               screen.NewestAuditTime = DateTime.Now;
-                //await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
-                //OrderScreenDetail detail = new OrderScreenDetail
-                //{
-                //	ScreenId = screen.Id
-                //};
-                //detail.Audit(_sessionContext.UserId, _sessionContext.UserName, _sessionContext.OrgId, _sessionContext.OrgName, 1);
-                //               await _orderScreenDetailRepository.AddAsync(detail, cancellationToken);
-                //    }
-                //    break;
                 case WorkflowModuleConsts.OrderDelay:
                 case WorkflowModuleConsts.OrderDelay:
                     var delay = await _orderDelayRepository.GetAsync(workflow.ExternalId, cancellationToken);
                     var delay = await _orderDelayRepository.GetAsync(workflow.ExternalId, cancellationToken);
                     if (delay != null)
                     if (delay != null)
                     {
                     {
-                        delay.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
+                        //delay.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
+                        delay.DelayState = isReviewPass ? EDelayState.Pass : EDelayState.NoPass;
+                        await _orderDelayRepository.Updateable(delay)
+                            .UpdateColumns(d => d.DelayState)
+                            .ExecuteCommandAsync(cancellationToken);
                         if (isReviewPass)
                         if (isReviewPass)
                         {
                         {
-                            delay.DelayState = isReviewPass ? EDelayState.Pass : EDelayState.NoPass;
-                            await _orderDelayRepository.UpdateAsync(delay, cancellationToken);
-
                             //处理工单延期
                             //处理工单延期
                             await _orderApplication.DelayOrderExpiredTimeAsync(delay.OrderId, delay.DelayNum,
                             await _orderApplication.DelayOrderExpiredTimeAsync(delay.OrderId, delay.DelayNum,
                                 delay.DelayUnit, delay.IsProDelay, cancellationToken);
                                 delay.DelayUnit, delay.IsProDelay, cancellationToken);
                         }
                         }
-                        else
-                        {
-                            delay.DelayState = EDelayState.NoPass;
-                            await _orderDelayRepository.UpdateAsync(delay, cancellationToken);
-                        }
                     }
                     }
                     break;
                     break;
                 case WorkflowModuleConsts.OrderTerminate:
                 case WorkflowModuleConsts.OrderTerminate:

+ 6 - 20
src/Hotline.Application/Orders/OrderApplication.cs

@@ -3572,11 +3572,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         // 6、班长特提至话务部,办理对象非必选,没选择则所有坐席都可以查看和办理
         // 6、班长特提至话务部,办理对象非必选,没选择则所有坐席都可以查看和办理
         //泸州需求:
         //泸州需求:
         /* 1、特提(仅针对特提到热线中心节点)
         /* 1、特提(仅针对特提到热线中心节点)
-           1.1、工单特提回话务部,办理对象需调整所有坐席都可以查看和办理
-           1.2、工单特提到派单组或者班长审批等其它热线中心节点,只有之前办理人才能办理
+           1.1、工单特提到话务部、派单组或者班长审批等其它热线中心节点,只有之前办理人才能办理
            2、退回功能(仅针对退回到热线中心节点)
            2、退回功能(仅针对退回到热线中心节点)
-           2.1、退回到话务部节点,只有之前受理人才能办理;
-           2.2、退回到派单组或者班长审批等其它热线中心节点,只有之前办理人才能办理
+           2.1、退回到热线中心各节点,只有之前办理人才能办理;
          */
          */
 
 
         if (workflow.FlowType is not EFlowType.Handle) return null;
         if (workflow.FlowType is not EFlowType.Handle) return null;
@@ -3730,12 +3728,10 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         // 6、班长特提至话务部,办理对象非必选,没选择则所有坐席都可以查看和办理
         // 6、班长特提至话务部,办理对象非必选,没选择则所有坐席都可以查看和办理
         //泸州需求:
         //泸州需求:
         /* 1、特提(仅针对特提到热线中心节点)
         /* 1、特提(仅针对特提到热线中心节点)
-           1.1、工单特提回话务部,办理对象需调整所有坐席都可以查看和办理
-           1.2、工单特提到派单组或者班长审批等其它热线中心节点,只有之前办理人才能办理
-           2、退回功能(仅针对退回到热线中心节点)
-           2.1、退回到话务部节点,只有之前受理人才能办理;
-           2.2、退回到派单组或者班长审批等其它热线中心节点,只有之前办理人才能办理
-         */
+             1.1、工单特提到话务部、派单组或者班长审批等其它热线中心节点,只有之前办理人才能办理
+             2、退回功能(仅针对退回到热线中心节点)
+             2.1、退回到热线中心各节点,只有之前办理人才能办理;
+        */
 
 
         if (workflow.FlowType is not EFlowType.Handle) return null;
         if (workflow.FlowType is not EFlowType.Handle) return null;
 
 
@@ -3850,16 +3846,6 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 switch (prevStepDefine.BusinessType)
                 switch (prevStepDefine.BusinessType)
                 {
                 {
                     case EBusinessType.Seat:
                     case EBusinessType.Seat:
-                        var define = prevStepDefine.HandlerTypeItems.First();
-                        rsp = new StepAssignInfo
-                        {
-                            FlowAssignType = EFlowAssignType.Role,
-                            RoleId = define.Key,
-                            RoleName = define.Value,
-                            Key = define.Key,
-                            Value = define.Value,
-                        };
-                        break;
                     case EBusinessType.Send:
                     case EBusinessType.Send:
                     case EBusinessType.CenterMonitor:
                     case EBusinessType.CenterMonitor:
                     case EBusinessType.CenterLeader:
                     case EBusinessType.CenterLeader:

+ 1 - 1
src/Hotline.Application/Snapshot/IInviteCodeApplication.cs

@@ -11,7 +11,7 @@ using System.Threading.Tasks;
 namespace Hotline.Application.Snapshot;
 namespace Hotline.Application.Snapshot;
 public interface IInviteCodeApplication
 public interface IInviteCodeApplication
 {
 {
-    Task AddInviteCodeAsync(AddInviteCodeInDto dto);
+    Task<string> AddInviteCodeAsync(AddInviteCodeInDto dto);
 
 
     /// <summary>
     /// <summary>
     /// 删除邀请码
     /// 删除邀请码

+ 2 - 2
src/Hotline.Application/Snapshot/InviteCodeApplication.cs

@@ -26,7 +26,7 @@ public class InviteCodeApplication : IInviteCodeApplication, IScopeDependency
         _inviteCodeRecordRepository = inviteCodeRecordRepository;
         _inviteCodeRecordRepository = inviteCodeRecordRepository;
     }
     }
 
 
-    public async Task AddInviteCodeAsync(AddInviteCodeInDto dto)
+    public async Task<string> AddInviteCodeAsync(AddInviteCodeInDto dto)
     {
     {
         if (_inviteCodeRepository.Queryable().Where(m => m.OrgName == dto.OrgName).Any())
         if (_inviteCodeRepository.Queryable().Where(m => m.OrgName == dto.OrgName).Any())
         {
         {
@@ -37,7 +37,7 @@ public class InviteCodeApplication : IInviteCodeApplication, IScopeDependency
         {
         {
             throw UserFriendlyException.SameMessage("开始邀请码不能大于结束邀请码");
             throw UserFriendlyException.SameMessage("开始邀请码不能大于结束邀请码");
         }
         }
-        await _inviteCodeRepository.AddAsync(entity);
+        return await _inviteCodeRepository.AddAsync(entity);
     }
     }
 
 
     /// <summary>
     /// <summary>

+ 9 - 6
src/Hotline.Application/StatisticalReport/IOrderReportApplication.cs

@@ -1,5 +1,6 @@
 using Hotline.Orders;
 using Hotline.Orders;
 using Hotline.Settings;
 using Hotline.Settings;
+using Hotline.Settings.Hotspots;
 using Hotline.Share.Dtos.Bi;
 using Hotline.Share.Dtos.Bi;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Requests;
 using Hotline.Share.Requests;
@@ -149,12 +150,14 @@ namespace Hotline.Application.StatisticalReport
         /// <returns></returns>
         /// <returns></returns>
         Task<DataTable> ExportQueryVisitNoSatisfiedAsync(IReadOnlyList<SystemDicData> dissatisfiedReason, List<dynamic>? list, List<string> addColumnName);
         Task<DataTable> ExportQueryVisitNoSatisfiedAsync(IReadOnlyList<SystemDicData> dissatisfiedReason, List<dynamic>? list, List<string> addColumnName);
 
 
-        /// <summary>
-        /// 部门不满意统计明细
-        /// </summary>
-        /// <param name="dto"></param>
-        /// <returns></returns>
-        ISugarQueryable<OrderVisitDetail> BiQueryVisitNoSatisfiedDetail(BiQueryVisitNoSatisfiedDetailDto dto);
+        Task<DataTable> ExportHotPortJoinOrgStatisticsAsync(IReadOnlyList<Hotspot> dissatisfiedReason, List<dynamic>? list, List<string> addColumnName);
+
+		/// <summary>
+		/// 部门不满意统计明细
+		/// </summary>
+		/// <param name="dto"></param>
+		/// <returns></returns>
+		ISugarQueryable<OrderVisitDetail> BiQueryVisitNoSatisfiedDetail(BiQueryVisitNoSatisfiedDetailDto dto);
 
 
         /// <summary>
         /// <summary>
         /// 未签收统计
         /// 未签收统计

+ 87 - 6
src/Hotline.Application/StatisticalReport/OrderReportApplication.cs

@@ -7,6 +7,7 @@ using Hotline.Identity.Accounts;
 using Hotline.Orders;
 using Hotline.Orders;
 using Hotline.SeedData;
 using Hotline.SeedData;
 using Hotline.Settings;
 using Hotline.Settings;
+using Hotline.Settings.Hotspots;
 using Hotline.Settings.TimeLimits;
 using Hotline.Settings.TimeLimits;
 using Hotline.Share.Dtos.Bi;
 using Hotline.Share.Dtos.Bi;
 using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.CallCenter;
@@ -2436,12 +2437,92 @@ namespace Hotline.Application.StatisticalReport
             return dataTable;
             return dataTable;
         }
         }
 
 
-        /// <summary>
-        /// 部门不满意统计明细
-        /// </summary>
-        /// <param name="dto"></param>
-        /// <returns></returns>
-        [HttpGet("visit-nosatisfied-detail")]
+
+		public async Task<DataTable> ExportHotPortJoinOrgStatisticsAsync(IReadOnlyList<Hotspot> dissatisfiedReason, List<dynamic>? list, List<string> addColumnName)
+		{
+			var dataTable = new DataTable();
+			foreach (var item in addColumnName)
+			{
+				dataTable.Columns.Add(item);
+			}
+
+			Dictionary<string, DataRow> dicRow = new();
+
+			// 先拿部门名称
+			// bug 部门名称重复时有问题
+			// 循环填充 首列 数据
+			foreach (var item in list)
+			{
+				foreach (var property in (IDictionary<string, object>)item)
+				{
+					if (property.Key == "OrgName")
+					{
+						var name = property.Value.ToString();
+						if (string.IsNullOrEmpty(name)) continue;
+						if (dicRow.Any(m => m.Key == name)) continue;
+						var dr = dataTable.NewRow();
+						dr[0] = name;
+						dicRow.Add(name, dr);
+					}
+				}
+			}
+
+			var drCount = dataTable.NewRow();
+			drCount[0] = "合计";
+			dicRow.Add("合计", drCount);
+
+			for (int i = 0; i < dissatisfiedReason.Count; i++)
+			{ // 循环填充列数据
+
+				var total = 0;
+				for (int l = 0; l < list.Count; l++)
+				{
+					var columnIndex = i + 2;
+					var value = string.Empty;
+					var orgName = string.Empty;
+					foreach (var property in (IDictionary<string, object>)list[l])
+					{
+						if (property.Key.ToLower().Equals("orgname")) orgName = property.Value.ToString();
+						if (property.Key.ToLower().Equals(dissatisfiedReason[i].Id))
+						{
+							value = property.Value.ToString();
+							total += int.Parse(value!);
+						}
+					}
+					if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(orgName))
+					{
+						dicRow[orgName!][columnIndex] = value;
+					}
+					if (l + 1 == list.Count)
+						dicRow["合计"][columnIndex] = total;
+				}
+			}
+
+			foreach (var item in dicRow)
+			{
+                //小计
+                var index = 0;
+                var subtotal = 0;
+				foreach (var item2 in item.Value.ItemArray)
+				{
+                    if (index >1)
+                    {
+                        subtotal += int.Parse(item2.ToString());
+					}
+                    index++;
+				}
+                item.Value[1] = subtotal.ToString();
+				dataTable.Rows.Add(item.Value);
+			}
+			return dataTable;
+		}
+
+		/// <summary>
+		/// 部门不满意统计明细
+		/// </summary>
+		/// <param name="dto"></param>
+		/// <returns></returns>
+		[HttpGet("visit-nosatisfied-detail")]
         public ISugarQueryable<OrderVisitDetail> BiQueryVisitNoSatisfiedDetail(BiQueryVisitNoSatisfiedDetailDto dto)
         public ISugarQueryable<OrderVisitDetail> BiQueryVisitNoSatisfiedDetail(BiQueryVisitNoSatisfiedDetailDto dto)
         {
         {
             var IsCenter = _sessionContext.OrgIsCenter;
             var IsCenter = _sessionContext.OrgIsCenter;

+ 8 - 1
src/Hotline.Repository.SqlSugar/BaseRepository.cs

@@ -368,7 +368,14 @@ namespace Hotline.Repository.SqlSugar
 
 
         public async Task UpdateAsync(TEntity entity, bool ignoreNullColumns = true, CancellationToken cancellationToken = default)
         public async Task UpdateAsync(TEntity entity, bool ignoreNullColumns = true, CancellationToken cancellationToken = default)
         {
         {
-            _serviceProvider.GetService<DatabaseEventDispatcher>()?.Dispatch(entity, DataFilterType.UpdateByObject, true);
+            try
+            {
+                _serviceProvider.GetService<DatabaseEventDispatcher>()?.Dispatch(entity, DataFilterType.UpdateByObject, true);
+            }
+            catch (Exception e)
+            {
+                var msg = e.Message;
+            }
             await Db.Updateable(entity)
             await Db.Updateable(entity)
                 .IgnoreColumns(ignoreAllNullColumns: ignoreNullColumns)
                 .IgnoreColumns(ignoreAllNullColumns: ignoreNullColumns)
                 .IgnoreColumns(d => d.CreationTime)
                 .IgnoreColumns(d => d.CreationTime)

+ 14 - 6
src/Hotline.Repository.SqlSugar/Orders/OrderRepository.cs

@@ -133,7 +133,7 @@ namespace Hotline.Repository.SqlSugar.Orders
             return propertyInfo.GetValue(obj, null);
             return propertyInfo.GetValue(obj, null);
         }
         }
 
 
-        public async Task<object> HotPortJoinOrgStatistics(DateTime StartTime, DateTime EndTime, bool IsCenter, string? OrgCode)
+        public async Task<(IReadOnlyList<Hotspot> hotSpotList, List<dynamic>? list)> HotPortJoinOrgStatistics(DateTime StartTime, DateTime EndTime, bool IsCenter, string? OrgCode)
         {
         {
             //查询一级热点
             //查询一级热点
             var hotSpotList = await Db.Queryable<Hotspot>().Where(x => string.IsNullOrEmpty(x.ParentId)).ToListAsync();
             var hotSpotList = await Db.Queryable<Hotspot>().Where(x => string.IsNullOrEmpty(x.ParentId)).ToListAsync();
@@ -159,7 +159,7 @@ namespace Hotline.Repository.SqlSugar.Orders
                     }).ToPivotListAsync(x => x.Key, x => new { x.OrgCode, x.OrgName, x.HotSorpName }, x => x.Sum(x => x.Count));
                     }).ToPivotListAsync(x => x.Key, x => new { x.OrgCode, x.OrgName, x.HotSorpName }, x => x.Sum(x => x.Count));
                 listReturn.AddRange(table);
                 listReturn.AddRange(table);
             }
             }
-            return new { HotSpot = hotSpotList, Data = listReturn };
+            return (hotSpotList, listReturn);
         }
         }
 
 
 
 
@@ -1843,7 +1843,9 @@ namespace Hotline.Repository.SqlSugar.Orders
                 .WhereIF(!string.IsNullOrEmpty(dto.ContentRetrieval), x => x.VisitContent.Contains(dto.ContentRetrieval!))
                 .WhereIF(!string.IsNullOrEmpty(dto.ContentRetrieval), x => x.VisitContent.Contains(dto.ContentRetrieval!))
                 .WhereIF(!string.IsNullOrEmpty(dto.LevelOneOrg), x => x.OrderVisit.Order.OrgLevelOneName.Contains(dto.LevelOneOrg))//一级部门名称
                 .WhereIF(!string.IsNullOrEmpty(dto.LevelOneOrg), x => x.OrderVisit.Order.OrgLevelOneName.Contains(dto.LevelOneOrg))//一级部门名称
                 .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), x => x.OrderVisit.Order.ActualHandleOrgName.Contains(dto.ActualHandleOrgName))// 接办部门
                 .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), x => x.OrderVisit.Order.ActualHandleOrgName.Contains(dto.ActualHandleOrgName))// 接办部门
-                .Select(x => new OrgVisitDetailListResp()
+                .WhereIF(dto.IsScreen.HasValue && dto.IsScreen.Value ,x=> SqlFunc.Subqueryable<OrderScreen>().Where(q => q.OrderId == x.OrderVisit.OrderId && q.VisitDetailId == x.Id).Any())
+				.WhereIF(dto.IsScreen.HasValue && dto.IsScreen.Value == false, x => SqlFunc.Subqueryable<OrderScreen>().Where(q => q.OrderId == x.OrderVisit.OrderId && q.VisitDetailId == x.Id).NotAny())
+				.Select(x => new OrgVisitDetailListResp()
                 {
                 {
                     Id = x.Id,
                     Id = x.Id,
                     OrderId = x.OrderVisit.Order.Id,
                     OrderId = x.OrderVisit.Order.Id,
@@ -1869,7 +1871,9 @@ namespace Hotline.Repository.SqlSugar.Orders
                     ActualHandleOrgName = x.OrderVisit.Order.ActualHandleOrgName,
                     ActualHandleOrgName = x.OrderVisit.Order.ActualHandleOrgName,
                     IsProvinceOrder = x.OrderVisit.Order.Source == ESource.ProvinceStraight ? true : false
                     IsProvinceOrder = x.OrderVisit.Order.Source == ESource.ProvinceStraight ? true : false
                 }).MergeTable().OrderByIF(string.IsNullOrEmpty(dto.SortField), x => x.VisitTime, OrderByType.Desc)
                 }).MergeTable().OrderByIF(string.IsNullOrEmpty(dto.SortField), x => x.VisitTime, OrderByType.Desc)
-                .OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, x => x.CreationTime, OrderByType.Asc) //受理时间升序
+				.OrderByIF(dto is { SortField: "orderScreenStatusText", SortRule: 0 }, x => x.OrderScreenStatus, OrderByType.Asc)
+				.OrderByIF(dto is { SortField: "orderScreenStatusText", SortRule: 1 }, x => x.OrderScreenStatus, OrderByType.Desc) 
+				.OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, x => x.CreationTime, OrderByType.Asc) //受理时间升序
                 .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, x => x.CreationTime, OrderByType.Desc) //受理时间降序
                 .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, x => x.CreationTime, OrderByType.Desc) //受理时间降序
                 .OrderByIF(dto is { SortField: "visitTime", SortRule: 0 }, x => x.VisitTime, OrderByType.Asc) //回访时间升序
                 .OrderByIF(dto is { SortField: "visitTime", SortRule: 0 }, x => x.VisitTime, OrderByType.Asc) //回访时间升序
                 .OrderByIF(dto is { SortField: "visitTime", SortRule: 1 }, x => x.VisitTime, OrderByType.Desc) //回访时间降序
                 .OrderByIF(dto is { SortField: "visitTime", SortRule: 1 }, x => x.VisitTime, OrderByType.Desc) //回访时间降序
@@ -1911,7 +1915,9 @@ namespace Hotline.Repository.SqlSugar.Orders
                 .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, x => x.OrderVisit.Order.Source != ESource.ProvinceStraight)
                 .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, x => x.OrderVisit.Order.Source != ESource.ProvinceStraight)
                 .WhereIF(!string.IsNullOrEmpty(dto.ContentRetrieval), x => x.VisitContent.Contains(dto.ContentRetrieval!))
                 .WhereIF(!string.IsNullOrEmpty(dto.ContentRetrieval), x => x.VisitContent.Contains(dto.ContentRetrieval!))
                 .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), x => x.OrderVisit.Order.ActualHandleOrgName.Contains(dto.ActualHandleOrgName!))
                 .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), x => x.OrderVisit.Order.ActualHandleOrgName.Contains(dto.ActualHandleOrgName!))
-                .Select(x => new OrgVisitDetailListResp
+				.WhereIF(dto.IsScreen.HasValue && dto.IsScreen.Value, x => SqlFunc.Subqueryable<OrderScreen>().Where(q => q.OrderId == x.OrderVisit.OrderId && q.VisitDetailId == x.Id).Any())
+				.WhereIF(dto.IsScreen.HasValue && dto.IsScreen.Value == false, x => SqlFunc.Subqueryable<OrderScreen>().Where(q => q.OrderId == x.OrderVisit.OrderId && q.VisitDetailId == x.Id).NotAny())
+				.Select(x => new OrgVisitDetailListResp
                 {
                 {
                     Id = x.Id,
                     Id = x.Id,
                     OrderId = x.OrderVisit.Order.Id,
                     OrderId = x.OrderVisit.Order.Id,
@@ -1937,7 +1943,9 @@ namespace Hotline.Repository.SqlSugar.Orders
                     ActualHandleOrgName = x.OrderVisit.Order.ActualHandleOrgName
                     ActualHandleOrgName = x.OrderVisit.Order.ActualHandleOrgName
                 }).MergeTable()
                 }).MergeTable()
                 .OrderByIF(string.IsNullOrEmpty(dto.SortField), x => x.VisitTime, OrderByType.Desc)
                 .OrderByIF(string.IsNullOrEmpty(dto.SortField), x => x.VisitTime, OrderByType.Desc)
-                .OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, x => x.CreationTime, OrderByType.Asc) //受理时间升序
+				.OrderByIF(dto is { SortField: "orderScreenStatusText", SortRule: 0 }, x => x.OrderScreenStatus, OrderByType.Asc)
+				.OrderByIF(dto is { SortField: "orderScreenStatusText", SortRule: 1 }, x => x.OrderScreenStatus, OrderByType.Desc)
+				.OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, x => x.CreationTime, OrderByType.Asc) //受理时间升序
                 .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, x => x.CreationTime, OrderByType.Desc) //受理时间降序
                 .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, x => x.CreationTime, OrderByType.Desc) //受理时间降序
                 .OrderByIF(dto is { SortField: "visitTime", SortRule: 0 }, x => x.VisitTime, OrderByType.Asc) //回访时间升序
                 .OrderByIF(dto is { SortField: "visitTime", SortRule: 0 }, x => x.VisitTime, OrderByType.Asc) //回访时间升序
                 .OrderByIF(dto is { SortField: "visitTime", SortRule: 1 }, x => x.VisitTime, OrderByType.Desc) //回访时间降序
                 .OrderByIF(dto is { SortField: "visitTime", SortRule: 1 }, x => x.VisitTime, OrderByType.Desc) //回访时间降序

+ 6 - 1
src/Hotline.Share/Dtos/Bi/BiOrderDto.cs

@@ -76,7 +76,12 @@ namespace Hotline.Share.Dtos.Bi
         /// 接办部门
         /// 接办部门
         /// </summary>
         /// </summary>
         public string? ActualHandleOrgName { get; set; }
         public string? ActualHandleOrgName { get; set; }
-    }
+
+		/// <summary>
+		/// 是否甄别
+		/// </summary>
+		public bool? IsScreen { get; set; }
+	}
 
 
     public record HighFrequencyCallStatisticsRequest : PagedRequest
     public record HighFrequencyCallStatisticsRequest : PagedRequest
     {
     {

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

@@ -451,7 +451,7 @@ namespace Hotline.Share.Dtos.Order
         /// 甄别状态
         /// 甄别状态
         /// </summary>
         /// </summary>
         public EScreenStatus? OrderScreenStatus { get; set; }
         public EScreenStatus? OrderScreenStatus { get; set; }
-        public string? OrderScreenStatusText => OrderScreenStatus?.GetDescription();
+        public string? OrderScreenStatusText => OrderScreenStatus.HasValue && OrderScreenStatus != null ? OrderScreenStatus?.GetDescription() : "未甄别";
 
 
         /// <summary>
         /// <summary>
         /// 回访内容
         /// 回访内容

+ 6 - 1
src/Hotline.Share/Requests/PagedKeywordRequest.cs

@@ -352,7 +352,7 @@ public record ExportHotPortJoinOrgStatisticsRequest
 	public List<string> AddColumnName { get; set; } = new();
 	public List<string> AddColumnName { get; set; } = new();
 }
 }
 
 
-public record  HotPortJoinOrgStatisticsRequestDetail: PagedKeywordRequest
+public record  HotPortJoinOrgStatisticsRequestDetail: PagedRequest
 {
 {
 	public DateTime StartTime { get; set; }
 	public DateTime StartTime { get; set; }
 
 
@@ -678,6 +678,11 @@ public record OrgVisitDetailListReq : PagedKeywordRequest
     /// 内容检索(回访内容)
     /// 内容检索(回访内容)
     /// </summary>
     /// </summary>
     public string? ContentRetrieval { get; set; }
     public string? ContentRetrieval { get; set; }
+
+    /// <summary>
+    /// 是否甄别
+    /// </summary>
+    public bool? IsScreen { get; set; }
 }
 }
 
 
 
 

+ 1 - 10
src/Hotline/Orders/IOrderDomainService.cs

@@ -115,15 +115,6 @@ namespace Hotline.Orders
         /// <param name="cancellationToken"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
         /// <returns></returns>
         Task VisitNoneByCancelPublishAsync(string orderId, CancellationToken cancellationToken);
         Task VisitNoneByCancelPublishAsync(string orderId, CancellationToken cancellationToken);
-
-        /// <summary>
-        /// 查询退回操作目标节点的指派方式
-        /// </summary>
-        ReverseFlowStepAssignInfo GetOrderPreviousAssignInfo(EBusinessType targetStepBusinessType, StepAssignInfo? handler);
-
-        /// <summary>
-        /// 查询特提操作目标节点的指派方式
-        /// </summary>
-        ReverseFlowStepAssignInfo GetOrderRecallAssignInfo(EBusinessType targetStepBusinessType, StepAssignInfo? handler);
+        
     }
     }
 }
 }

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

@@ -6,6 +6,7 @@ using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.Order;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 using Hotline.Share.Dtos.Bi;
 using Hotline.Share.Dtos.Bi;
+using Hotline.Settings.Hotspots;
 
 
 namespace Hotline.Orders
 namespace Hotline.Orders
 {
 {
@@ -18,7 +19,7 @@ namespace Hotline.Orders
         Task OrderScreenRevisionVisit(string VisitId, bool canHandle, CancellationToken cancellationToken);
         Task OrderScreenRevisionVisit(string VisitId, bool canHandle, CancellationToken cancellationToken);
         Task FileAsync(Order order, CancellationToken cancellationToken);
         Task FileAsync(Order order, CancellationToken cancellationToken);
 
 
-        Task<object> HotPortJoinOrgStatistics(DateTime StartTime, DateTime EndTime, bool IsCenter, string? OrgCode);
+        Task<(IReadOnlyList<Hotspot> hotSpotList, List<dynamic>? list)> HotPortJoinOrgStatistics(DateTime StartTime, DateTime EndTime, bool IsCenter, string? OrgCode);
         ISugarQueryable<Order> HotPortJoinOrgStatisticsDetail(HotPortJoinOrgStatisticsRequestDetail dto);
         ISugarQueryable<Order> HotPortJoinOrgStatisticsDetail(HotPortJoinOrgStatisticsRequestDetail dto);
 
 
 
 

+ 0 - 130
src/Hotline/Orders/OrderDomainService.cs

@@ -411,136 +411,6 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         }
         }
     }
     }
 
 
-    /// <summary>
-    /// 查询退回操作目标节点的指派方式
-    /// </summary>
-    public ReverseFlowStepAssignInfo GetOrderPreviousAssignInfo(EBusinessType targetStepBusinessType, StepAssignInfo? handler)
-    {
-        //自贡需求:
-        // 1. 工单退回、特提、重办到话务部节点时,所有坐席都可以查看和办理
-        // 2. 退回到派单组时需执行平均分配逻辑
-        //宜宾需求:
-        // 1、退回至话务部:所有坐席都可以查看和办理(除某些场景下本来就需指定办理对象,如:发布时退回……)
-        // 2、退回至派单组:默认退给之前的派单员(除某些场景下本来就需指定办理对象,如:发布时退回……)
-        // 3、话务员特提至话务部:根据特提申请时候选择来,指定的办理对象才能查看和办理
-        // 4、派单员特提至派单组:根据特提申请时候选择来,指定的办理对象才能查看和办理
-        // 5、班长特提至派单组,办理对象必选(已实现)
-        // 6、班长特提至话务部,办理对象非必选,没选择则所有坐席都可以查看和办理
-        //泸州需求:
-        /* 1、特提(仅针对特提到热线中心节点)
-           1.1、工单特提回话务部,办理对象需调整所有坐席都可以查看和办理
-           1.2、工单特提到派单组或者班长审批等其它热线中心节点,只有之前办理人才能办理
-           2、退回功能(仅针对退回到热线中心节点)
-           2.1、退回到话务部节点,只有之前受理人才能办理;
-           2.2、退回到派单组或者班长审批等其它热线中心节点,只有之前办理人才能办理  
-         */
-
-        var rsp = new ReverseFlowStepAssignInfo(EReverseFlowStepCreationPolicy.OriginStepUser);
-
-        switch (targetStepBusinessType)
-        {
-            case EBusinessType.Seat:
-                if (_appOptions.Value.IsZiGong || _appOptions.Value.IsYiBin)
-                {
-                    rsp.ReverseFlowStepCreationPolicy = EReverseFlowStepCreationPolicy.OriginDefinition;
-                }
-                break;
-            case EBusinessType.Send:
-                if (_appOptions.Value.IsZiGong)
-                {
-                    if (handler is null)
-                        throw new UserFriendlyException("参数异常,退回派单组需要通过平均派单指定办理人");
-
-                    rsp.ReverseFlowStepCreationPolicy = EReverseFlowStepCreationPolicy.AssignHandler;
-                    rsp.StepAssignInfo = handler;
-                }
-                break;
-            case EBusinessType.Department:
-                rsp.ReverseFlowStepCreationPolicy = EReverseFlowStepCreationPolicy.OriginStepOrg;
-                break;
-            case EBusinessType.DepartmentLeader:
-                break;
-            case EBusinessType.CenterMonitor:
-                break;
-            case EBusinessType.CenterLeader:
-                break;
-            case EBusinessType.Unknown:
-                break;
-            case EBusinessType.File:
-            default:
-                throw new ArgumentOutOfRangeException(nameof(targetStepBusinessType), targetStepBusinessType, null);
-        }
-
-        return rsp;
-    }
-
-    /// <summary>
-    /// 查询特提操作目标节点的指派方式
-    /// </summary>
-    public ReverseFlowStepAssignInfo GetOrderRecallAssignInfo(EBusinessType targetStepBusinessType, StepAssignInfo? handler)
-    {
-        //自贡需求:
-        // 1. 工单退回、特提、重办到话务部节点时,所有坐席都可以查看和办理
-        // 2. 退回到派单组时需执行平均分配逻辑
-        //宜宾需求:
-        // 1、退回至话务部:所有坐席都可以查看和办理(除某些场景下本来就需指定办理对象,如:发布时退回……)
-        // 2、退回至派单组:默认退给之前的派单员(除某些场景下本来就需指定办理对象,如:发布时退回……)
-        // 3、话务员特提至话务部:根据特提申请时候选择来,指定的办理对象才能查看和办理
-        // 4、派单员特提至派单组:根据特提申请时候选择来,指定的办理对象才能查看和办理
-        // 5、班长特提至派单组,办理对象必选(已实现)
-        // 6、班长特提至话务部,办理对象非必选,没选择则所有坐席都可以查看和办理
-        //泸州需求:
-        /* 1、特提(仅针对特提到热线中心节点)
-           1.1、工单特提回话务部,办理对象需调整所有坐席都可以查看和办理
-           1.2、工单特提到派单组或者班长审批等其它热线中心节点,只有之前办理人才能办理
-           2、退回功能(仅针对退回到热线中心节点)
-           2.1、退回到话务部节点,只有之前受理人才能办理;
-           2.2、退回到派单组或者班长审批等其它热线中心节点,只有之前办理人才能办理
-         */
-
-        var rsp = new ReverseFlowStepAssignInfo(EReverseFlowStepCreationPolicy.OriginStepUser);
-
-        switch (targetStepBusinessType)
-        {
-            case EBusinessType.Seat:
-                if (_appOptions.Value.IsYiBin && handler is not null)
-                {
-                    rsp.ReverseFlowStepCreationPolicy = EReverseFlowStepCreationPolicy.AssignHandler;
-                    rsp.StepAssignInfo = handler;
-                }
-                else
-                {
-                    rsp.ReverseFlowStepCreationPolicy = EReverseFlowStepCreationPolicy.OriginDefinition;
-                }
-                break;
-            case EBusinessType.Send:
-                if (_appOptions.Value.IsZiGong || _appOptions.Value.IsYiBin)
-                {
-                    if(handler is null)
-                        throw new UserFriendlyException("参数异常,特提派单组需要指定办理人");
-                    rsp.ReverseFlowStepCreationPolicy = EReverseFlowStepCreationPolicy.AssignHandler;
-                    rsp.StepAssignInfo = handler;
-                }
-                break;
-            case EBusinessType.Department:
-                rsp.ReverseFlowStepCreationPolicy = EReverseFlowStepCreationPolicy.OriginStepOrg;
-                break;
-            case EBusinessType.DepartmentLeader:
-                break;
-            case EBusinessType.CenterMonitor:
-                break;
-            case EBusinessType.CenterLeader:
-                break;
-            case EBusinessType.Unknown:
-                break;
-            case EBusinessType.File:
-            default:
-                throw new ArgumentOutOfRangeException(nameof(targetStepBusinessType), targetStepBusinessType, null);
-        }
-
-        return rsp;
-    }
-
     public async Task<Order> GetOrderAsync(string? orderId, bool withHotspot = false, bool withAcceptor = false,
     public async Task<Order> GetOrderAsync(string? orderId, bool withHotspot = false, bool withAcceptor = false,
         bool withExtension = false, CancellationToken cancellationToken = default)
         bool withExtension = false, CancellationToken cancellationToken = default)
     {
     {

+ 3 - 1
test/Hotline.Tests/Application/DefaultCallApplicationTest.cs

@@ -5,6 +5,7 @@ using Hotline.CallCenter.Calls;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Identity.Roles;
 using Hotline.Orders;
 using Hotline.Orders;
+using Hotline.Settings;
 using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Enums.CallCenter;
@@ -14,6 +15,7 @@ using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using Shouldly;
 using SqlSugar.Extensions;
 using SqlSugar.Extensions;
+using XF.Domain.Cache;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 
 
 namespace Hotline.Tests.Application;
 namespace Hotline.Tests.Application;
@@ -25,7 +27,7 @@ public class DefaultCallApplicationTest : TestBase
     public readonly IFixture _fixture;
     public readonly IFixture _fixture;
     private readonly IOrderRepository _orderRepository;
     private readonly IOrderRepository _orderRepository;
 
 
-    public DefaultCallApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, XingTangCallApplication defaultCallApplication, IOrderVisitRepository orderVisitRepository, IRepository<CallNative> callNativeRepository, IOrderRepository orderRepository, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount)
+    public DefaultCallApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, XingTangCallApplication defaultCallApplication, IOrderVisitRepository orderVisitRepository, IRepository<CallNative> callNativeRepository, IOrderRepository orderRepository, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount, ITypedCache<SystemSetting> cacheSettingData) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount, cacheSettingData)
     {
     {
         _fixture = new Fixture();
         _fixture = new Fixture();
         _defaultCallApplication = defaultCallApplication;
         _defaultCallApplication = defaultCallApplication;

+ 3 - 1
test/Hotline.Tests/Application/IndustryApplicationTest.cs

@@ -13,6 +13,8 @@ using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using Shouldly;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
+using Hotline.Settings;
+using XF.Domain.Cache;
 
 
 namespace Hotline.Tests.Application;
 namespace Hotline.Tests.Application;
 public class IndustryApplicationTest : TestBase
 public class IndustryApplicationTest : TestBase
@@ -21,7 +23,7 @@ public class IndustryApplicationTest : TestBase
     private readonly IIndustryRepository _industryRepository;
     private readonly IIndustryRepository _industryRepository;
     private readonly ISystemOrganizeRepository _systemOrganizeRepository;
     private readonly ISystemOrganizeRepository _systemOrganizeRepository;
 
 
-    public IndustryApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, IIndustryApplication industryApplication, IIndustryRepository industryRepository, ISystemOrganizeRepository systemOrganizeRepository) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository)
+    public IndustryApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, IIndustryApplication industryApplication, IIndustryRepository industryRepository, ISystemOrganizeRepository systemOrganizeRepository, ITypedCache<SystemSetting> cacheSettingData) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository, cacheSettingData)
     {
     {
         _industryApplication = industryApplication;
         _industryApplication = industryApplication;
         _industryRepository = industryRepository;
         _industryRepository = industryRepository;

+ 28 - 2
test/Hotline.Tests/Application/InviteCodeApplicationTest.cs

@@ -2,22 +2,39 @@
 using Hotline.Application.Snapshot;
 using Hotline.Application.Snapshot;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Identity.Roles;
+using Hotline.Repository.SqlSugar.Snapshot;
+using Hotline.Settings;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Snapshot.Interfaces;
 using Hotline.Snapshot.Interfaces;
 using Hotline.Users;
 using Hotline.Users;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using Shouldly;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Authentications;
+using XF.Domain.Cache;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 
 
 namespace Hotline.Tests.Application;
 namespace Hotline.Tests.Application;
 public class InviteCodeApplicationTest : TestBase
 public class InviteCodeApplicationTest : TestBase
 {
 {
     private readonly IInviteCodeApplication _inviteCodeApplication;
     private readonly IInviteCodeApplication _inviteCodeApplication;
+    private readonly ISnapshotApplication _snapshotApplication;
+    private readonly IInviteCodeRepository _inviteCodeRepository;
+    private readonly ISessionContext _sessionContext;
+    private readonly IInviteCodeRecordRepository _inviteCodeRecordRepository;
 
 
-    public InviteCodeApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, IInviteCodeApplication inviteCodeApplication) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository)
+    public InviteCodeApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, IInviteCodeApplication inviteCodeApplication, ISnapshotApplication snapshotApplication, IInviteCodeRepository inviteCodeRepository, ISessionContext sessionContext, IInviteCodeRecordRepository inviteCodeRecordRepository, ITypedCache<SystemSetting> cacheSettingData) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository, cacheSettingData)
     {
     {
         _inviteCodeApplication = inviteCodeApplication;
         _inviteCodeApplication = inviteCodeApplication;
+        _snapshotApplication = snapshotApplication;
+        this._inviteCodeRepository = inviteCodeRepository;
+        _sessionContext = sessionContext;
+        _inviteCodeRecordRepository = inviteCodeRecordRepository;
     }
     }
 
 
     [Fact]
     [Fact]
@@ -30,10 +47,19 @@ public class InviteCodeApplicationTest : TestBase
             EndCode = 200,
             EndCode = 200,
         };
         };
 
 
-        await _inviteCodeApplication.AddInviteCodeAsync(inDto);
+        var id = await _inviteCodeApplication.AddInviteCodeAsync(inDto);
 
 
         var items = _inviteCodeApplication.GetInviteCodeItems().ToList();
         var items = _inviteCodeApplication.GetInviteCodeItems().ToList();
         items.Count.ShouldNotBe(0);
         items.Count.ShouldNotBe(0);
+        await _inviteCodeRepository.RemoveAsync(id);
+
+        SetWeiXin();
+        await _thirdAccountRepository.Updateable()
+            .SetColumns(m => m.InvitationCode, null)
+            .Where(m => m.OpenId == _sessionContext.OpenId)
+            .ExecuteCommandAsync();
+        await _inviteCodeRecordRepository.Removeable().Where(m => m.InviteCode == "110").ExecuteCommandAsync();
+        await _snapshotApplication.SaveInvitationCodeAsync(new SaveInvitationCodeInDto { InvitationCode = "110"});
 
 
         var statics = await _inviteCodeApplication.GetInviteCodeStatisticAsync(new GetInviteCodeStatisticInDto 
         var statics = await _inviteCodeApplication.GetInviteCodeStatisticAsync(new GetInviteCodeStatisticInDto 
         {
         {

+ 11 - 2
test/Hotline.Tests/Application/KnowApplicationTest.cs

@@ -3,6 +3,8 @@ using Hotline.Application.Knowledge;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Identity.Roles;
 using Hotline.KnowledgeBase;
 using Hotline.KnowledgeBase;
+using Hotline.KnowledgeBase.Notifies;
+using Hotline.Settings;
 using Hotline.Share.Dtos.Knowledge;
 using Hotline.Share.Dtos.Knowledge;
 using Hotline.Share.Tools;
 using Hotline.Share.Tools;
 using Hotline.Snapshot.Interfaces;
 using Hotline.Snapshot.Interfaces;
@@ -12,6 +14,13 @@ using MediatR;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using Shouldly;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using XF.Domain.Cache;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 
 
 namespace Hotline.Tests.Application;
 namespace Hotline.Tests.Application;
@@ -29,8 +38,8 @@ public class KnowApplicationTest : TestBase
         IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor,
         IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor,
         IKnowApplication knowApplication, IMediator mediator, IRepository<KnowledgeBase.Knowledge> knowledgeRepository,
         IKnowApplication knowApplication, IMediator mediator, IRepository<KnowledgeBase.Knowledge> knowledgeRepository,
         IKnowledgeDomainService knowledgeDomainService, IRepository<KnowledgeWord> knowledgeWordRepository,
         IKnowledgeDomainService knowledgeDomainService, IRepository<KnowledgeWord> knowledgeWordRepository,
-        IRepository<KnowledgeHotWord> knowledgeHotWordRepository, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount)
-        : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount)
+        IRepository<KnowledgeHotWord> knowledgeHotWordRepository, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount, ITypedCache<SystemSetting> cacheSettingData)
+        : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount, cacheSettingData)
     {
     {
         _knowApplication = knowApplication;
         _knowApplication = knowApplication;
         _mediator = mediator;
         _mediator = mediator;

+ 46 - 10
test/Hotline.Tests/Application/OrderSnapshotApplicationTest.cs

@@ -5,6 +5,7 @@ using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Identity.Roles;
 using Hotline.Repository.SqlSugar.Extensions;
 using Hotline.Repository.SqlSugar.Extensions;
 using Hotline.Repository.SqlSugar.Snapshot;
 using Hotline.Repository.SqlSugar.Snapshot;
+using Hotline.Settings;
 using Hotline.Share.Dtos;
 using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Enums.Snapshot;
 using Hotline.Share.Enums.Snapshot;
@@ -15,7 +16,14 @@ using Hotline.Tests.Mock;
 using Hotline.Users;
 using Hotline.Users;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
+using NPOI.SS.Formula.Functions;
 using Shouldly;
 using Shouldly;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Cache;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 
 
 namespace Hotline.Tests.Application;
 namespace Hotline.Tests.Application;
@@ -32,7 +40,7 @@ public class OrderSnapshotApplicationTest : TestBase
     private readonly IRedPackRecordRepository _redPackRecordRepository;
     private readonly IRedPackRecordRepository _redPackRecordRepository;
     private readonly ISnapshotLabelLogRepository _snapshotLabelLogRepository;
     private readonly ISnapshotLabelLogRepository _snapshotLabelLogRepository;
 
 
-    public OrderSnapshotApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, OrderServiceMock orderServiceMock, ISystemDicDataCacheManager systemDicDataCacheManager, IOrderSnapshotRepository orderSnapshotRepository, IOrderSnapshotApplication orderSnapshotApplication, ISnapshotApplication snapshotApplication, IIndustryLogRepository industryLogRepository, ICommunityInfoRepository communityInfoRepository, IRedPackAuditRepository redPackAuditRepository, IRedPackRecordRepository redPackRecordRepository, ISnapshotLabelLogRepository snapshotLabelLogRepository) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository)
+    public OrderSnapshotApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, OrderServiceMock orderServiceMock, ISystemDicDataCacheManager systemDicDataCacheManager, IOrderSnapshotRepository orderSnapshotRepository, IOrderSnapshotApplication orderSnapshotApplication, ISnapshotApplication snapshotApplication, IIndustryLogRepository industryLogRepository, ICommunityInfoRepository communityInfoRepository, IRedPackAuditRepository redPackAuditRepository, IRedPackRecordRepository redPackRecordRepository, ISnapshotLabelLogRepository snapshotLabelLogRepository, ITypedCache<SystemSetting> cacheSettingData) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository, cacheSettingData)
     {
     {
         _orderServiceMock = orderServiceMock;
         _orderServiceMock = orderServiceMock;
         _systemDicDataCacheManager = systemDicDataCacheManager;
         _systemDicDataCacheManager = systemDicDataCacheManager;
@@ -46,9 +54,35 @@ public class OrderSnapshotApplicationTest : TestBase
         _snapshotLabelLogRepository = snapshotLabelLogRepository;
         _snapshotLabelLogRepository = snapshotLabelLogRepository;
     }
     }
 
 
+    /// <summary>
+    /// 随手拍网格员超时:
+    /// </summary>
+    /// <returns></returns>
+    [Fact]
+    public async Task SnapshotWorkflow_Guider_Timeout_Test()
+    {
+        SetSettingCache(SettingConstants.OvertimeBack, "0.00027778");
+        var order = _orderServiceMock.CreateSnapshotOrder(SetWeiXin)
+            .办理到网格员(SetZuoXi)
+            .StepHandle(async order =>
+            {
+                Thread.Sleep(30 * 1000);
+            }
+            ).GetCreateResult();
+        order.Id.ShouldNotBeNull();
+    }
+
     /// <summary>
     /// <summary>
     /// 随手拍办理流程:
     /// 随手拍办理流程:
-    ///     到网格员
+    ///     坐席
+    ///     网格员
+    ///     派单员
+    ///     一级部门
+    ///     归档
+    ///     发布工单
+    ///     政法委部门审核网格红包
+    ///     应急局部门审核网格员红包
+    ///     部门审核市民红包
     /// </summary>
     /// </summary>
     /// <returns></returns>
     /// <returns></returns>
     [Fact]
     [Fact]
@@ -114,15 +148,16 @@ public class OrderSnapshotApplicationTest : TestBase
             .办理到一级部门(SetPaiDanYuan)
             .办理到一级部门(SetPaiDanYuan)
             .办理到归档(Set一级部门)
             .办理到归档(Set一级部门)
             .发布工单(SetZuoXi, inputLable.Select(m => new Kv(m.DicDataName, m.DicDataName)).ToList())
             .发布工单(SetZuoXi, inputLable.Select(m => new Kv(m.DicDataName, m.DicDataName)).ToList())
-            .StepHandle(async order => {
-                    var log = _snapshotLabelLogRepository.Queryable().Where(m => m.OrderId == order.Id).First();
-                    log.ShouldNotBeNull();
-                    var snapshot = _orderSnapshotRepository.Get(order.Id);
-                    snapshot.LabelName.ShouldBe(string.Join(',', inputLable.Select(m => m.DicDataName)),"label异常");
-                    })
+            .StepHandle(async order =>
+            {
+                var log = _snapshotLabelLogRepository.Queryable().Where(m => m.OrderId == order.Id).First();
+                log.ShouldNotBeNull();
+                var snapshot = _orderSnapshotRepository.Get(order.Id);
+                snapshot.LabelName.ShouldBe(string.Join(',', inputLable.Select(m => m.DicDataName)), "label异常");
+            })
             .部门审核网格员红包(Set政法委)
             .部门审核网格员红包(Set政法委)
             .部门审核网格员红包(Set应急管理局)
             .部门审核网格员红包(Set应急管理局)
-            .StepHandle(async order => 
+            .StepHandle(async order =>
             {
             {
                 var redPackRecord = _redPackRecordRepository.Queryable()
                 var redPackRecord = _redPackRecordRepository.Queryable()
                 .Where(m => m.OrderId == order.Id && m.PeopleType == EReadPackUserType.Guider)
                 .Where(m => m.OrderId == order.Id && m.PeopleType == EReadPackUserType.Guider)
@@ -130,7 +165,8 @@ public class OrderSnapshotApplicationTest : TestBase
                 redPackRecord.Amount.ShouldNotBe(0);
                 redPackRecord.Amount.ShouldNotBe(0);
             })
             })
             .部门审核市民红包(Set应急管理局)
             .部门审核市民红包(Set应急管理局)
-            .StepHandle(async order => {
+            .StepHandle(async order =>
+            {
                 var redPackAudit = _redPackAuditRepository.Queryable().Where(m => m.OrderId == order.Id).First();
                 var redPackAudit = _redPackAuditRepository.Queryable().Where(m => m.OrderId == order.Id).First();
                 redPackAudit.Status.ShouldBe(ERedPackAuditStatus.Agree);
                 redPackAudit.Status.ShouldBe(ERedPackAuditStatus.Agree);
                 var redPackRecord = _redPackRecordRepository.Queryable().Where(m => m.OrderId == order.Id).First();
                 var redPackRecord = _redPackRecordRepository.Queryable().Where(m => m.OrderId == order.Id).First();

+ 9 - 1
test/Hotline.Tests/Application/RedPackApplicationTest.cs

@@ -2,6 +2,7 @@
 using Hotline.Application.Snapshot;
 using Hotline.Application.Snapshot;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Identity.Roles;
+using Hotline.Settings;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Enums.Snapshot;
 using Hotline.Share.Enums.Snapshot;
 using Hotline.Snapshot.Interfaces;
 using Hotline.Snapshot.Interfaces;
@@ -9,6 +10,13 @@ using Hotline.Users;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using Shouldly;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Cache;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 
 
 namespace Hotline.Tests.Application;
 namespace Hotline.Tests.Application;
@@ -17,7 +25,7 @@ public class RedPackApplicationTest : TestBase
     private readonly IRedPackApplication _redPackApplication;
     private readonly IRedPackApplication _redPackApplication;
     private readonly IRedPackRecordRepository _redPackRecordRepository;
     private readonly IRedPackRecordRepository _redPackRecordRepository;
 
 
-    public RedPackApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, IRedPackApplication redPackApplication, IRedPackRecordRepository redPackRecordRepository) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository)
+    public RedPackApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, IRedPackApplication redPackApplication, IRedPackRecordRepository redPackRecordRepository, ITypedCache<SystemSetting> cacheSettingData) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository, cacheSettingData)
     {
     {
         _redPackApplication = redPackApplication;
         _redPackApplication = redPackApplication;
         _redPackRecordRepository = redPackRecordRepository;
         _redPackRecordRepository = redPackRecordRepository;

+ 4 - 1
test/Hotline.Tests/Application/SnapshotApplicationTest.cs

@@ -7,6 +7,8 @@ using Hotline.File;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Identity.Roles;
 using Hotline.Orders;
 using Hotline.Orders;
+using Hotline.Repository.SqlSugar.Extensions;
+using Hotline.Settings;
 using Hotline.Share.Dtos.Article;
 using Hotline.Share.Dtos.Article;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Enums;
 using Hotline.Share.Enums;
@@ -21,6 +23,7 @@ using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using Shouldly;
 using XF.Domain.Authentications;
 using XF.Domain.Authentications;
+using XF.Domain.Cache;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 using XF.Utility.EnumExtensions;
 using XF.Utility.EnumExtensions;
 
 
@@ -44,7 +47,7 @@ public class SnapshotApplicationTest : TestBase
     private readonly IRedPackApplication _redPackApplication;
     private readonly IRedPackApplication _redPackApplication;
     private readonly IOrderSnapshotApplication _orderSnapshotApplication;
     private readonly IOrderSnapshotApplication _orderSnapshotApplication;
 
 
-    public SnapshotApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, ISnapshotApplication snapshotApplication, IIdentityAppService identityAppService, IRepository<RedPackRecord> redPackRecordRepository, IIndustryApplication industryApplication, IIndustryRepository industryRepository, IFileRepository fileRepository, OrderServiceMock orderServiceMock, IOrderRepository orderRepository, IOrderSnapshotRepository orderSnapshotRepository, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount, ISessionContext sessionContext, IGuiderSystemService guiderSystemService, ISystemSettingCacheManager systemSettingCacheManager, ICommunityInfoRepository communityInfoRepository, IIndustryLogRepository industryLogRepository, IRedPackApplication redPackApplication, IOrderSnapshotApplication orderSnapshotApplication) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount)
+    public SnapshotApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, ISnapshotApplication snapshotApplication, IIdentityAppService identityAppService, IRepository<RedPackRecord> redPackRecordRepository, IIndustryApplication industryApplication, IIndustryRepository industryRepository, IFileRepository fileRepository, OrderServiceMock orderServiceMock, IOrderRepository orderRepository, IOrderSnapshotRepository orderSnapshotRepository, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount, ISessionContext sessionContext, IGuiderSystemService guiderSystemService, ISystemSettingCacheManager systemSettingCacheManager, ICommunityInfoRepository communityInfoRepository, IIndustryLogRepository industryLogRepository, IRedPackApplication redPackApplication, IOrderSnapshotApplication orderSnapshotApplication, ITypedCache<SystemSetting> cacheSettingData) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount, cacheSettingData)
     {
     {
         _snapshotApplication = snapshotApplication;
         _snapshotApplication = snapshotApplication;
         _identityAppService = identityAppService;
         _identityAppService = identityAppService;

+ 7 - 1
test/Hotline.Tests/Application/SystemSettingCacheManagerTest.cs

@@ -8,6 +8,12 @@ using Hotline.Users;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using Shouldly;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Cache;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 
 
 namespace Hotline.Tests.Application;
 namespace Hotline.Tests.Application;
@@ -17,7 +23,7 @@ public class SystemSettingCacheManagerTest : TestBase
     private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
     private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
     private readonly IRepository<SystemSetting> _systemSettingRepository;
     private readonly IRepository<SystemSetting> _systemSettingRepository;
 
 
-    public SystemSettingCacheManagerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, ISystemSettingCacheManager systemSettingCacheManager, ISystemDicDataCacheManager systemDicDataCacheManager, IRepository<SystemSetting> systemSettingRepository, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount)
+    public SystemSettingCacheManagerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, ISystemSettingCacheManager systemSettingCacheManager, ISystemDicDataCacheManager systemDicDataCacheManager, IRepository<SystemSetting> systemSettingRepository, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount, ITypedCache<SystemSetting> cacheSettingData) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount, cacheSettingData)
     {
     {
         _systemSettingCacheManager = systemSettingCacheManager;
         _systemSettingCacheManager = systemSettingCacheManager;
         _systemDicDataCacheManager = systemDicDataCacheManager;
         _systemDicDataCacheManager = systemDicDataCacheManager;

+ 8 - 1
test/Hotline.Tests/Controller/IndustryControllerTest.cs

@@ -2,19 +2,26 @@
 using Hotline.Api.Controllers.Snapshot;
 using Hotline.Api.Controllers.Snapshot;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Identity.Roles;
+using Hotline.Settings;
 using Hotline.Snapshot.Interfaces;
 using Hotline.Snapshot.Interfaces;
 using Hotline.Users;
 using Hotline.Users;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using Shouldly;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Cache;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 
 
 namespace Hotline.Tests.Controller;
 namespace Hotline.Tests.Controller;
 public class IndustryControllerTest : TestBase
 public class IndustryControllerTest : TestBase
 {
 {
     private readonly IndustryController _industryController;
     private readonly IndustryController _industryController;
-    public IndustryControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, IndustryController industryController) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository)
+    public IndustryControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, IndustryController industryController, ITypedCache<SystemSetting> cacheSettingData) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository, cacheSettingData)
     {
     {
         _industryController = industryController;
         _industryController = industryController;
         _industryController.ControllerContext = new ControllerContext
         _industryController.ControllerContext = new ControllerContext

+ 10 - 1
test/Hotline.Tests/Controller/KnowledgeControllerTest.cs

@@ -1,6 +1,9 @@
 using Hotline.Api.Controllers;
 using Hotline.Api.Controllers;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Identity.Roles;
+using Hotline.KnowledgeBase;
+using Hotline.Settings;
+using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.Knowledge;
 using Hotline.Share.Dtos.Knowledge;
 using Hotline.Share.Enums.KnowledgeBase;
 using Hotline.Share.Enums.KnowledgeBase;
 using Hotline.Snapshot.Interfaces;
 using Hotline.Snapshot.Interfaces;
@@ -10,6 +13,12 @@ using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using Shouldly;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Cache;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 
 
 namespace Hotline.Tests.Controller;
 namespace Hotline.Tests.Controller;
@@ -19,7 +28,7 @@ public class KnowledgeControllerTest : TestBase
     private readonly KnowledgeController _knowledgeController;
     private readonly KnowledgeController _knowledgeController;
     private readonly IRepository<KnowledgeBase.Knowledge> _knowledgeRepository;
     private readonly IRepository<KnowledgeBase.Knowledge> _knowledgeRepository;
 
 
-    public KnowledgeControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, KnowledgeServiceMock knowledgeServiceMock, KnowledgeController knowledgeController, IRepository<KnowledgeBase.Knowledge> knowledgeRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount)
+    public KnowledgeControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, KnowledgeServiceMock knowledgeServiceMock, KnowledgeController knowledgeController, IRepository<KnowledgeBase.Knowledge> knowledgeRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount, ITypedCache<SystemSetting> cacheSettingData) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount, cacheSettingData)
     {
     {
         _knowledgeServiceMock = knowledgeServiceMock;
         _knowledgeServiceMock = knowledgeServiceMock;
         _knowledgeController = knowledgeController;
         _knowledgeController = knowledgeController;

+ 10 - 2
test/Hotline.Tests/Controller/OrderControllerTest.cs

@@ -31,6 +31,14 @@ using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using Shouldly;
 using SqlSugar;
 using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using XF.Domain.Authentications;
+using XF.Domain.Cache;
 using XF.Domain.Exceptions;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 
 
@@ -67,8 +75,8 @@ public class OrderControllerTest : TestBase
         IRepository<CallidRelation> callIdRelationRepository, XingTangCallApplication defaultCallApplication,
         IRepository<CallidRelation> callIdRelationRepository, XingTangCallApplication defaultCallApplication,
         ISugarUnitOfWork<CapDbContext> capDbContext, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdService,
         ISugarUnitOfWork<CapDbContext> capDbContext, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdService,
         IThirdAccountRepository thirdAccount, IIndustryRepository industryRepository, IOrderSnapshotRepository orderSnapshotRepository,
         IThirdAccountRepository thirdAccount, IIndustryRepository industryRepository, IOrderSnapshotRepository orderSnapshotRepository,
-        ISystemLogRepository systemLogRepository, IOrderVisitDomainService orderVisitDomainService, IRepository<OrderVisitDetail> orderVisitDetailRepository, ISystemDicDataCacheManager systemDicDataCacheManager)
-        : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount)
+        ISystemLogRepository systemLogRepository, IOrderVisitDomainService orderVisitDomainService, IRepository<OrderVisitDetail> orderVisitDetailRepository, ISystemDicDataCacheManager systemDicDataCacheManager, ITypedCache<SystemSetting> cacheSettingData)
+        : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount, cacheSettingData)
     {
     {
         _hotspotRepository = hotspotRepository;
         _hotspotRepository = hotspotRepository;
         _orderController = orderController;
         _orderController = orderController;

+ 8 - 1
test/Hotline.Tests/Controller/SnapshotControllerTest.cs

@@ -5,6 +5,7 @@ using Hotline.Api.Controllers.Snapshot;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Identity.Roles;
 using Hotline.Orders;
 using Hotline.Orders;
+using Hotline.Settings;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Enums.Snapshot;
 using Hotline.Share.Enums.Snapshot;
 using Hotline.Share.Tools;
 using Hotline.Share.Tools;
@@ -14,6 +15,12 @@ using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Shouldly;
 using Shouldly;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Cache;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 
 
 namespace Hotline.Tests.Controller;
 namespace Hotline.Tests.Controller;
@@ -26,7 +33,7 @@ public class SnapshotControllerTest : TestBase
     private readonly IEasyCachingProvider _easyCaching;
     private readonly IEasyCachingProvider _easyCaching;
     private readonly IRedisCachingProvider _redisCaching;
     private readonly IRedisCachingProvider _redisCaching;
 
 
-    public SnapshotControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, SnapshotController snapshotController, IOrderRepository orderRepository, IOrderSnapshotRepository orderSnapshotRepository, IIndustryRepository industryRepository, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount, IEasyCachingProvider easyCaching, IRedisCachingProvider redisCaching) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount)
+    public SnapshotControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, SnapshotController snapshotController, IOrderRepository orderRepository, IOrderSnapshotRepository orderSnapshotRepository, IIndustryRepository industryRepository, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount, IEasyCachingProvider easyCaching, IRedisCachingProvider redisCaching, ITypedCache<SystemSetting> cacheSettingData) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount, cacheSettingData)
     {
     {
         _snapshotController = snapshotController;
         _snapshotController = snapshotController;
         _snapshotController.ControllerContext = new ControllerContext
         _snapshotController.ControllerContext = new ControllerContext

+ 2 - 1
test/Hotline.Tests/Domain/OrderVisitDomainServiceTest.cs

@@ -21,6 +21,7 @@ using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
 using Shouldly;
 using Shouldly;
+using XF.Domain.Cache;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 
 
 namespace Hotline.Tests.Domain;
 namespace Hotline.Tests.Domain;
@@ -37,7 +38,7 @@ public class OrderVisitDomainServiceTest : TestBase
     private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
     private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
     private readonly ISystemLogRepository _logRepository;
     private readonly ISystemLogRepository _logRepository;
 
 
-    public OrderVisitDomainServiceTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IOrderVisitDomainService orderVisitDomainService, IOrderVisitRepository orderVisitRepository, IRepository<OrderVisitDetail> orderVisitDetailRepository, Publisher publisher, IOrderRepository orderRepository, OrderServiceMock orderServiceMock, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount, ISettingOrderVisitSmsReplyRuleRepository settingOrderVisitSmsReplyRuleRepository, ISystemDicDataCacheManager systemDicDataCacheManager, IOptionsSnapshot<AppConfiguration> appOptions, ISystemLogRepository logRepository) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount)
+    public OrderVisitDomainServiceTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IOrderVisitDomainService orderVisitDomainService, IOrderVisitRepository orderVisitRepository, IRepository<OrderVisitDetail> orderVisitDetailRepository, Publisher publisher, IOrderRepository orderRepository, OrderServiceMock orderServiceMock, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount, ISettingOrderVisitSmsReplyRuleRepository settingOrderVisitSmsReplyRuleRepository, ISystemDicDataCacheManager systemDicDataCacheManager, IOptionsSnapshot<AppConfiguration> appOptions, ISystemLogRepository logRepository, ITypedCache<SystemSetting> cacheSettingData) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount, cacheSettingData)
     {
     {
         _orderVisitDomainService = orderVisitDomainService;
         _orderVisitDomainService = orderVisitDomainService;
         _orderVisitRepository = orderVisitRepository;
         _orderVisitRepository = orderVisitRepository;

+ 1 - 0
test/Hotline.Tests/SqlSuger/CapDbExtensions.cs

@@ -7,6 +7,7 @@ public static class CAPDbExtensions
 {
 {
     public static IServiceCollection AddCAPDb(this IServiceCollection services, IConfiguration configuration)
     public static IServiceCollection AddCAPDb(this IServiceCollection services, IConfiguration configuration)
     {
     {
+        var config = configuration.GetConnectionString("CAP");
         SqlSugarScope sqlSugar = new(new ConnectionConfig() 
         SqlSugarScope sqlSugar = new(new ConnectionConfig() 
         { 
         { 
             DbType = DbType.PostgreSQL,
             DbType = DbType.PostgreSQL,

+ 11 - 4
test/Hotline.Tests/TestBase.cs

@@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using XF.Domain.Authentications;
 using XF.Domain.Authentications;
+using XF.Domain.Cache;
 using XF.Domain.Repository;
 using XF.Domain.Repository;
 
 
 namespace Hotline.Tests;
 namespace Hotline.Tests;
@@ -29,11 +30,9 @@ public class TestBase
     public readonly IHttpContextAccessor _httpContextAccessor;
     public readonly IHttpContextAccessor _httpContextAccessor;
     public readonly IThirdIdentiyService _thirdIdentiyService;
     public readonly IThirdIdentiyService _thirdIdentiyService;
     public readonly IThirdAccountRepository _thirdAccountRepository;
     public readonly IThirdAccountRepository _thirdAccountRepository;
+    private readonly ITypedCache<SystemSetting> _cacheSettingData;
 
 
-
-    public TestBase(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController,
-        IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor,
-        IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository)
+    public TestBase(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, ITypedCache<SystemSetting> cacheSettingData)
     {
     {
         _thirdAccountRepository = thirdAccountRepository;
         _thirdAccountRepository = thirdAccountRepository;
         _thirdIdentiyService = thirdIdentiyService;
         _thirdIdentiyService = thirdIdentiyService;
@@ -55,6 +54,14 @@ public class TestBase
             SetZuoXi();
             SetZuoXi();
         }
         }
 
 
+        _cacheSettingData = cacheSettingData;
+    }
+
+    public void SetSettingCache(string code, string value)
+    {
+        _cacheSettingData.Remove(code);
+        var a = new SystemSetting { SettingValue = new List<string> { value } };
+        _cacheSettingData.Set(code, a);
     }
     }
 
 
     public void ChangeAppScopeYiBin()
     public void ChangeAppScopeYiBin()

+ 1 - 1
test/Hotline.Tests/appsettings.Development.json

@@ -120,7 +120,7 @@
             "UserName": "dev",
             "UserName": "dev",
             "Password": "123456",
             "Password": "123456",
             "HostName": "110.188.24.182",
             "HostName": "110.188.24.182",
-            "VirtualHost": "fwt-dev"
+            "VirtualHost": "fwt-unittest"
         }
         }
     },
     },
     //"SmsAccountInfo": {
     //"SmsAccountInfo": {