فهرست منبع

增加执法领域统计接口

guqiang 4 هفته پیش
والد
کامیت
3295f37a9e
23فایلهای تغییر یافته به همراه619 افزوده شده و 229 حذف شده
  1. 1 1
      src/Hotline.Api/Controllers/Bi/BiOrderController.cs
  2. 3 3
      src/Hotline.Api/Controllers/FwThirdController.cs
  3. 11 0
      src/Hotline.Api/Controllers/JudicialManagementOrdersController.cs
  4. 249 147
      src/Hotline.Api/Controllers/OrderController.cs
  5. 2 0
      src/Hotline.Api/Controllers/Snapshot/SnapshotOrderController.cs
  6. 2 2
      src/Hotline.Application/CallCenter/DefaultCallApplication.cs
  7. 27 0
      src/Hotline.Application/JudicialManagement/EnforcementApplication.cs
  8. 9 0
      src/Hotline.Application/JudicialManagement/IEnforcementApplication.cs
  9. 10 0
      src/Hotline.Application/Mappers/OrderMapperConfigs.cs
  10. 70 8
      src/Hotline.Application/OrderApp/OrderApplication.cs
  11. 15 0
      src/Hotline.Share/Dtos/File/FileDto.cs
  12. 36 1
      src/Hotline.Share/Dtos/JudicialManagement/EmDepartmentalProcessingStatisticsDto.cs
  13. 16 0
      src/Hotline.Share/Dtos/JudicialManagement/QueryEventClassificationStatisticsDto.cs
  14. 2 1
      src/Hotline.Share/Dtos/Order/OrderDto.cs
  15. 58 16
      src/Hotline.Share/Dtos/Order/OrderVisitDto.cs
  16. 6 1
      src/Hotline.Share/Enums/Order/ESource.cs
  17. 1 1
      src/Hotline.Share/Hotline.Share.csproj
  18. 9 4
      src/Hotline.Share/Mq/EventNames.Order.cs
  19. 2 2
      src/Hotline/Orders/Order.cs
  20. 62 39
      src/Hotline/Orders/OrderDomainService.cs
  21. 8 3
      src/Hotline/Orders/OrderVisit.cs
  22. 19 0
      src/Hotline/Orders/OrderVisitDetailCopy.cs
  23. 1 0
      test/Hotline.Tests/Application/DefaultCallApplicationTest.cs

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

@@ -3038,7 +3038,7 @@ namespace Hotline.Api.Controllers.Bi
 			var centerReportVisitd = await _orderVisitRepository.Queryable()
               .LeftJoin<Order>((x,o)=> x.OrderId == o.Id)
 			  .WhereIF(IdentityType.HasValue, (x, o) => o.IdentityType == IdentityType)
-			  .Where((x, o) => x.VisitTime >= StartTime && x.VisitTime <= EndTime)
+			  .Where((x, o) => x.VisitTime >= StartTime && x.VisitTime <= EndTime )
 			  .Select((x, o) => new CenterReportVisitdDto
 			  {
 				  Visitd = SqlFunc.AggregateSum(SqlFunc.IIF(x.VisitState == EVisitState.Visited, 1, 0)),//已回访

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

@@ -348,7 +348,7 @@ namespace Hotline.Api.Controllers
                 .WhereIF(!string.IsNullOrEmpty(dto.FlowEDate), (op, p) => p.StartTime <= DateTime.Parse(DateTime.Parse(dto.FlowEDate).ToString("yyyy-MM-dd 00:00:00")))// dto.FlowEDate
                 .WhereIF(!string.IsNullOrEmpty(dto.FlowFrom), (op, p) => p.FromName.Contains(dto.FlowFrom))
                 .WhereIF(dto.IdentityType.HasValue, (op, p) => p.IdentityType == dto.IdentityType)
-                .OrderByDescending((op, p) => p.CreationTime)
+                .OrderByDescending((op, p) => op.CreationTime)
                .Select((op, p) => new OrderListDto
                {
                    FlowID = p.Id,
@@ -388,8 +388,8 @@ namespace Hotline.Api.Controllers
             //            });
 
             var (total, items) = await queryNew
-                .OrderByDescending(p => p.PubDate)
-                 .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
+                //.OrderByDescending(op => op.PubDate)
+                .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
 
             //计算总页数
             int nPageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(total) / dto.PageSize));

+ 11 - 0
src/Hotline.Api/Controllers/JudicialManagementOrdersController.cs

@@ -695,6 +695,17 @@ namespace Hotline.Api.Controllers
             return new PagedDto<EnforcementOrderListDto>(total, items);
         }
 
+        /// <summary>
+        /// 执法领域统计
+        /// </summary>
+        /// <param name="queryIndustryOrderStatisticsRequest"></param>
+        /// <returns></returns>
+        [HttpGet("enforcement_industry_statistics_order")]
+        public async Task<PagedDto<IndustryOrderStaticsDto>> QueryIndustryOrderStatics([FromQuery] QueryIndustryOrderStatisticsRequest queryIndustryOrderStatisticsRequest)
+        {
+            return await _enforcementApplication.QueryIndustryOrderStatics(queryIndustryOrderStatisticsRequest);
+        }
+
         /// <summary>
         /// 执法部门办件统计---明细---导出
         /// </summary>

+ 249 - 147
src/Hotline.Api/Controllers/OrderController.cs

@@ -1,10 +1,10 @@
-using DocumentFormat.OpenXml.Spreadsheet;
-using DotNetCore.CAP;
+using DotNetCore.CAP;
 using FluentValidation;
 using Hotline.Api.Filter;
 using Hotline.Application.CallCenter;
 using Hotline.Application.ExportExcel;
 using Hotline.Application.FlowEngine;
+using Hotline.Application.OrderApp;
 using Hotline.Application.Quality;
 using Hotline.Application.Snapshot.Contracts;
 using Hotline.Application.Systems;
@@ -48,7 +48,6 @@ using Hotline.Share.Dtos.Settings;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Enums.Article;
 using Hotline.Share.Enums.CallCenter;
-using Hotline.Share.Enums.Caselibrary;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Push;
@@ -64,18 +63,15 @@ using Hotline.Validators.FlowEngine;
 using Hotline.YbEnterprise.Sdk;
 using Mapster;
 using MapsterMapper;
-using MathNet.Numerics.LinearAlgebra.Factorization;
 using MediatR;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Options;
 using MiniExcelLibs;
-using NPOI.SS.Formula.Functions;
 using SqlSugar;
 using System.Text;
 using System.Text.Json;
 using System.Threading;
-using Hotline.Application.OrderApp;
 using XF.Domain.Authentications;
 using XF.Domain.Cache;
 using XF.Domain.Exceptions;
@@ -170,6 +166,7 @@ public class OrderController : BaseController
     private readonly IRepository<OrderComplement> _orderComplementRepository;
     private readonly ICircularRecordDomainService _circularRecordDomainService;
     private readonly IRepository<Hotline.Special.SpecialNumber> _specialNumberRepository;
+    private readonly IRepository<OrderVisitDetailCopy> _orderVisitDetailCopyRepository;
     private readonly IRepository<OrderEarlyWarning> _orderEarlyWarningRepository;
     private readonly IRepository<EarlyWarningSetting> _earlyWarningSettingRepository;
     private readonly IRepository<OrderTsDetails> _orderTsDetailsRepository;
@@ -250,6 +247,7 @@ public class OrderController : BaseController
         IRepository<OrderComplement> orderComplementRepository,
         ICircularRecordDomainService circularRecordDomainService,
         IRepository<Hotline.Special.SpecialNumber> specialNumberRepository,
+        IRepository<OrderVisitDetailCopy> orderVisitDetailCopyRepository,
         IRepository<OrderEarlyWarning> orderEarlyWarningRepository,
         IRepository<EarlyWarningSetting> earlyWarningSettingRepository,
         IRepository<OrderTsDetails> orderTsDetailsRepository)
@@ -328,7 +326,7 @@ public class OrderController : BaseController
         _systemOrganizeRepository = systemOrganizeRepository;
         _orderComplementRepository = orderComplementRepository;
         _circularRecordDomainService = circularRecordDomainService;
-        _specialNumberRepository = specialNumberRepository;
+        _orderVisitDetailCopyRepository = orderVisitDetailCopyRepository;
         _orderEarlyWarningRepository = orderEarlyWarningRepository;
         _earlyWarningSettingRepository = earlyWarningSettingRepository;
         _orderTsDetailsRepository = orderTsDetailsRepository;
@@ -691,40 +689,63 @@ public class OrderController : BaseController
         {
             try
             {
-                if (order.Source != ESource.ProvinceStraight && order.FileOrgIsCenter.Value == false)
+                if (_appOptions.Value.IsZiGong)
                 {
-                    var code = "";
-                    //受理类型为“投诉、举报”
-                    if ((order.AcceptTypeCode == "30" || order.AcceptTypeCode == "35") && orderVisit.VisitState != EVisitState.Visited)
+                    if (order.Source == ESource.ProvinceStraight)
                     {
-                        code = "1017";
-                        orderVisit.VisitState = EVisitState.SMSVisiting;
-                        await _orderVisitRepository.UpdateAsync(orderVisit);
+                        //发送查询短信
+                        var messageDto = new Share.Dtos.Push.MessageDto
+                        {
+                            PushBusiness = EPushBusiness.SearchSms,
+                            ExternalId = visitId,
+                            OrderId = order.Id,
+                            PushPlatform = EPushPlatform.Sms,
+                            Remark = order.Title,
+                            Name = order.FromName,
+                            TemplateCode = "1021",
+                            Params = new List<string>() { order.No, order.Password },
+                            TelNumber = order.Contact,
+                        };
+                        await _mediator.Publish(new PushMessageNotify(messageDto), HttpContext.RequestAborted);
                     }
-                    else
-                        code = "1018";
-
-                    var messageDto = new Share.Dtos.Push.MessageDto
+                }
+                else
+                {
+                    if (order.Source != ESource.ProvinceStraight && order.FileOrgIsCenter.Value == false)
                     {
-                        PushBusiness = EPushBusiness.SearchSms,
-                        ExternalId = visitId,
-                        OrderId = order.Id,
-                        PushPlatform = EPushPlatform.Sms,
-                        Remark = order.Title,
-                        Name = order.FromName,
-                        TemplateCode = code,
-                        Params = new List<string>() { order.No, order.Password },
-                        TelNumber = order.Contact,
-                    };
-                    await _mediator.Publish(new PushMessageNotify(messageDto), HttpContext.RequestAborted);
-
-                    // 发送短信后推送一个 48小时的延迟消息队列. 当消息队列收到消息时, 判断用户是否回复了, 如果未回复短信就 默认满意
-                    var delaySecond = _systemSettingCacheManager.DefaultVisitSmsDelaySecond;
-                    await _capPublisher.PublishDelayAsync(
-                        TimeSpan.FromSeconds(delaySecond),
-                        EventNames.UpdateVisitDelaySms,
-                        messageDto,
-                        cancellationToken: HttpContext.RequestAborted);
+                        var code = "";
+                        //受理类型为“投诉、举报”
+                        if ((order.AcceptTypeCode == "30" || order.AcceptTypeCode == "35") && orderVisit.VisitState != EVisitState.Visited)
+                        {
+                            code = "1017";
+                            orderVisit.VisitState = EVisitState.SMSVisiting;
+                            await _orderVisitRepository.UpdateAsync(orderVisit);
+                        }
+                        else
+                            code = "1018";
+
+                        var messageDto = new Share.Dtos.Push.MessageDto
+                        {
+                            PushBusiness = EPushBusiness.SearchSms,
+                            ExternalId = visitId,
+                            OrderId = order.Id,
+                            PushPlatform = EPushPlatform.Sms,
+                            Remark = order.Title,
+                            Name = order.FromName,
+                            TemplateCode = code,
+                            Params = new List<string>() { order.No, order.Password },
+                            TelNumber = order.Contact,
+                        };
+                        await _mediator.Publish(new PushMessageNotify(messageDto), HttpContext.RequestAborted);
+
+                        // 发送短信后推送一个 48小时的延迟消息队列. 当消息队列收到消息时, 判断用户是否回复了, 如果未回复短信就 默认满意
+                        var delaySecond = _systemSettingCacheManager.DefaultVisitSmsDelaySecond;
+                        await _capPublisher.PublishDelayAsync(
+                            TimeSpan.FromSeconds(delaySecond),
+                            EventNames.UpdateVisitDelaySms,
+                            messageDto,
+                            cancellationToken: HttpContext.RequestAborted);
+                    }
                 }
             }
             catch (Exception)
@@ -1091,6 +1112,53 @@ public class OrderController : BaseController
 
     #region 工单回访
 
+    /// <summary>
+    /// 获取修改历史记录
+    /// </summary>
+    /// <param name="id"></param>
+    /// <returns></returns>
+    [HttpGet("getordervisitdetailcopy/{id}")]
+    public async Task<OrderVisitDetailCopyDto> GetOrderVisitDetailCopy(string id)
+    {
+        var listCopyData = await _orderVisitDetailCopyRepository.Queryable()
+            .Where(p => p.VisitId == id)
+            .OrderByDescending(p => p.CreationTime)
+            .Take(1)
+            .ToListAsync();
+
+        var data = new OrderVisitDetailCopyDto();
+        if (listCopyData != null && listCopyData.Any())
+        {
+            //修改数据
+            var list = await _orderVisitDetailCopyRepository.Queryable().Where(p => p.BacthId == listCopyData[0].BacthId).OrderBy(p => p.VisitTarget).ToListAsync();
+            if (list != null && list.Any())
+            {
+                var orderVisitDetailCopyDtos = new List<OrderVisitDetailDto>();
+                foreach (var item in list)
+                {
+                    orderVisitDetailCopyDtos.Add(_mapper.Map<OrderVisitDetailDto>(item));
+                }
+                data.OrderVisitDetailCopyDtos = orderVisitDetailCopyDtos;
+                data.CreatorName = list[0].CreatorName;
+                data.CreationTime = list[0].CreationTime;
+            }
+
+            //正常数据
+            var listData = await _orderVisitedDetailRepository.Queryable().Where(p => p.VisitId == id).OrderBy(p => p.VisitTarget).ToListAsync();
+            if (listData != null && listData.Any())
+            {
+                var orderVisitDetailDtos = new List<OrderVisitDetailDto>();
+                foreach (var item in listData)
+                {
+                    orderVisitDetailDtos.Add(_mapper.Map<OrderVisitDetailDto>(item));
+                }
+                data.OrderVisitDetailDtos = orderVisitDetailDtos;
+            }
+        }
+
+        return data;
+    }
+
     /// <summary>
     /// 回访列表
     /// </summary>
@@ -5682,31 +5750,26 @@ public class OrderController : BaseController
         return order.WorkflowTraces.Count(d => d.IsOrigin && d.BusinessType == EBusinessType.Seat);
     }
 
-	#region 附件列表
+    #region 附件列表
 
-	/// <summary>
-	/// 获取工单所有文件
-	/// </summary>
-	/// <param name="id"></param>
-	/// <returns></returns>
-	[HttpGet("all_file/{id}")]
-	public async Task<List<FileDto>> GetOrderAllFile(string id)
-	{
-		var order = await _orderRepository.GetAsync(id);
-		var steps = await _workflowStepRepository.Queryable().Where(x => x.WorkflowId == order.WorkflowId).ToListAsync();
-		var allFiles = new List<FileDto>();
-		if (order != null && _sessionContext.OrgIsCenter)
-		{
-            if (order.FileJson != null )
+    /// <summary>
+    /// 获取工单所有文件
+    /// </summary>
+    /// <param name="id"></param>
+    /// <returns></returns>
+    [HttpGet("all_file/{id}")]
+    public async Task<List<FileDto>> GetOrderAllFile(string id)
+    {
+        var order = await _orderRepository.GetAsync(id);
+        var steps = await _workflowStepRepository.Queryable().Where(x => x.WorkflowId == order.WorkflowId).ToListAsync();
+        var allFiles = new List<FileDto>();
+        if (order != null && _sessionContext.OrgIsCenter)
+        {
+            if (order.FileJson != null)
             {
 				var ids = order.FileJson.Select(x => x.Id).ToList();
 				allFiles = await _fileRepository.GetFilesAsync(ids, cancellationToken: HttpContext.RequestAborted);
-			}
-            if (order.ListFileJson!= null)
-            {
-				var listIds = order.ListFileJson.Select(x => x.Id).ToList();
-				var listFiles = await _fileRepository.GetFilesAsync(listIds, cancellationToken: HttpContext.RequestAborted);
-				allFiles.AddRange(listFiles);
+				allFiles.ForEach(x => x.GetStepName("工单受理"));
 			}
 		}
 		foreach (var step in steps)
@@ -5715,109 +5778,148 @@ public class OrderController : BaseController
 			{
 				var ids = step.FileJson.Select(x => x.Id).ToList();
 				var stepFiles = await _fileRepository.GetPermissionFilesAsync(ids, HttpContext.RequestAborted);
+				stepFiles.ForEach(x => x.GetStepName(step.Name));
 				allFiles.AddRange(stepFiles);
 			}
 		}
-        allFiles.ForEach(x => x.GetIsDelete(_sessionContext.RequiredUserId));
 		return allFiles;
 	}
 
 	/// <summary>
-	/// 新增附件 Classify ="附件列表上传"
+	/// 获取流程信息
 	/// </summary>
-	/// <param name="dtos"></param>
+	/// <param name="workflowId"></param>
 	/// <returns></returns>
-	[HttpPost("list/file_upload")]
-	[LogFilter("附件列表新增附件")]
-
-	public async Task Add([FromBody] OrderListUploadFilesDto dto)
+	[HttpGet("all_file/workflow/{workflowId}")]
+	public async Task<WorkflowDto> GetOrderWorkflowAsync(string workflowId)
 	{
+		var workflow = await _workflowDomainService.GetWorkflowAsync(workflowId, withSteps: true,
+			cancellationToken: HttpContext.RequestAborted);
+        var steps = _mapper.Map<List<WorkflowTraceDto>>(workflow.Steps);
+        var workflowDto = _mapper.Map<WorkflowDto>(workflow);
+        workflowDto.Traces = steps;
+        foreach (var item in workflowDto.Traces)
+        {
+            if (item.FileJson != null)
+            {
+                var ids = item.FileJson.Select(x => x.Id).ToList();
+                item.Files = await _fileRepository.GetFilesAsync(ids, HttpContext.RequestAborted);
+            }
+        }
+        return workflowDto;
+    }
+
+    /// <summary>
+    /// 附件列表补充附件
+    /// </summary>
+    /// <param name="dtos"></param>
+    /// <returns></returns>
+    [HttpPost("list/file_upload")]
+    [LogFilter("附件列表补充附件")]
+
+    public async Task Add([FromBody] OrderStepUploadFilesDto dto)
+    {
+        var order = await _orderRepository.GetAsync(dto.OrderId);
+        var step = await _workflowStepRepository.GetAsync(dto.StepId);
+
         var listFileJson = new List<FileJson>();
-		if (dto.Files.Any())
+        if (dto.Files.Any())
         {
-             listFileJson = await _fileRepository.AddFileAsync(dto.Files, dto.OrderId, "", HttpContext.RequestAborted);
-		}
-		await _orderRepository.Updateable().SetColumns(x => new Order { ListFileJson = listFileJson }).Where(x => x.Id == dto.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
-	}
+            listFileJson = await _fileRepository.AddFileAsync(dto.Files, dto.StepId, "", HttpContext.RequestAborted);
+        }
+        await _workflowStepRepository.Updateable().SetColumns(x => new WorkflowStep { FileJson = listFileJson }).Where(x => x.Id == dto.StepId).ExecuteCommandAsync(HttpContext.RequestAborted);
+        await _workflowTraceRepository.Updateable().SetColumns(x => new WorkflowTrace { FileJson = listFileJson }).Where(x => x.Id == dto.StepId).ExecuteCommandAsync(HttpContext.RequestAborted);
+
+        ////附件上传后推送省上
+        var orderDto = _mapper.Map<OrderDto>(order);
+        var flowDto = new OrderFlowDto
+        {
+            Order = orderDto,
+            WorkflowTrace = _mapper.Map<WorkflowTraceDto>(step),
+            ExpiredTimeChanged = false,
+            HandlerOrgLevel = step.HandlerOrgId.CalcOrgLevel()
+        };
+        await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFlowFile, flowDto, cancellationToken: HttpContext.RequestAborted);
+    }
 
-	#endregion
-
-	#endregion
-
-	#region 工单待办
-
-	///// <summary>
-	///// 查询待办工单
-	///// </summary>
-	//[HttpGet("waited")]
-	//public async Task<PagedDto<OrderDto>> QueryWaited([FromQuery] QueryOrderWaitedDto dto)
-	//{
-	//    var isHandledStep = dto.IsHandled.HasValue && dto.IsHandled.Value;
-	//    if (isHandledStep)
-	//        dto.QueryType = null;
-
-	//    var isAdmin = _orderDomainService.IsCheckAdmin();
-	//    var query = _orderRepository
-	//        .Queryable(hasHandledStep: isHandledStep, isAdmin: isAdmin)
-	//        .Includes(d => d.OrderSpecials);
-	//    if (dto.QueryType is 1 || dto.QueryType is 2)
-	//    {
-	//        query.WhereIF(dto.QueryType is 1, d => d.IsForwarded == false)
-	//            .WhereIF(dto.QueryType is 2, d => d.IsForwarded == true)
-	//            .Where(d => SqlFunc.Subqueryable<OrderSpecial>().Where(os => os.OrderId == d.Id && os.IsDeleted == false && os.SpecialType == ESpecialType.ReTransact)
-	//                .NotAny())
-	//            ;
-	//    }
-
-	//    var (total, items) = await query
-	//        .Where(d => d.Status != EOrderStatus.WaitForAccept &&
-	//                    d.Status != EOrderStatus.BackToUnAccept &&
-	//                    d.Status != EOrderStatus.SpecialToUnAccept &&
-	//                    d.Status != EOrderStatus.HandOverToUnAccept)
-	//        .WhereIF(dto.QueryType is 3,
-	//            d => SqlFunc.Subqueryable<OrderSpecial>().Where(os => os.OrderId == d.Id && os.IsDeleted == false && os.SpecialType == ESpecialType.ReTransact).Any())
-	//        .Where(d => SqlFunc.Subqueryable<OrderDelay>().Where(od => od.OrderId == d.Id && od.IsDeleted == false && od.DelayState == EDelayState.Examining).NotAny())
-	//        .Where(d => SqlFunc.Subqueryable<OrderSendBackAudit>().Where(osba => osba.OrderId == d.Id && osba.IsDeleted == false && osba.State == ESendBackAuditState.Apply)
-	//            .NotAny())
-	//        .Where(d => SqlFunc.Subqueryable<OrderSpecial>().Where(s => s.OrderId == d.Id && s.State == 0 && s.IsDeleted == false).NotAny())
-	//        .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
-	//        .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.StartsWith(dto.Keyword))
-	//        .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No == dto.No)
-	//        .WhereIF(!string.IsNullOrEmpty(dto.AreaCode), d => d.AreaCode == dto.AreaCode)
-	//        .WhereIF(dto.IsCounterSign.HasValue && dto.IsCounterSign == true, d => d.CounterSignType.HasValue)
-	//        .WhereIF(dto.IsCounterSign.HasValue && dto.IsCounterSign == false, d => d.CounterSignType == null)
-	//        .WhereIF(dto.ExpiredOrAlmostOverdue.HasValue && dto.ExpiredOrAlmostOverdue == true,
-	//            d => (d.ExpiredTime < DateTime.Now && d.Status < EOrderStatus.Filed) ||
-	//                 (d.ExpiredTime < d.ActualHandleTime && d.Status >= EOrderStatus.Filed)) //超期 未办
-	//        .WhereIF(dto.ExpiredOrAlmostOverdue.HasValue && dto.ExpiredOrAlmostOverdue == false,
-	//            d => d.NearlyExpiredTime < DateTime.Now && d.ExpiredTime > DateTime.Now) //即将超期 未办
-	//        .Where(d => d.Source < ESource.MLSQ || d.Source > ESource.WZSC)
-	//        .Where(d => d.Status != EOrderStatus.BackToProvince)
-	//        .WhereIF(!isHandledStep || _appOptions.Value.IsYiBin,d=>d.Status < EOrderStatus.Filed)
-	//        //.Where(d => SqlFunc.Subqueryable<OrderSpecial>().Where(os => os.OrderId == d.Id).NotAny())
-	//        //.Where(d => d.OrderSpecials.Any() == false || d.OrderSpecials.Any(s => s.State > 0))
-	//        .WhereIF(dto.StartTime.HasValue, d => d.StartTime >= dto.StartTime)
-	//        .WhereIF(dto.EndTime.HasValue, d => d.StartTime <= dto.EndTime)
-	//        .WhereIF(dto.IsUrgent.HasValue, d => d.IsUrgent == dto.IsUrgent!.Value)
-	//        .WhereIF(dto.Status.HasValue, d => d.Status == dto.Status)
-	//        //.OrderByDescending(d => d.IsUrgent)
-	//        .OrderByIF(string.IsNullOrEmpty(dto.SortField), d => d.StartTime, OrderByType.Desc)
-	//        .OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, d => d.CreationTime, OrderByType.Asc) //创建时间升序
-	//        .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, d => d.CreationTime, OrderByType.Desc) //创建时间降序
-	//        .OrderByIF(dto is { SortField: "startTime", SortRule: 0 }, d => d.StartTime, OrderByType.Asc) //受理时间升序
-	//        .OrderByIF(dto is { SortField: "startTime", SortRule: 1 }, d => d.StartTime, OrderByType.Desc) //受理时间降序
-	//        .OrderByIF(dto is { SortField: "expiredTime", SortRule: 0 }, d => d.ExpiredTime, OrderByType.Asc) //期满时间升序
-	//        .OrderByIF(dto is { SortField: "expiredTime", SortRule: 1 }, d => d.ExpiredTime, OrderByType.Desc) //期满时间降序
-	//        .ToPagedListAsync(dto, HttpContext.RequestAborted);
-
-	//    return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
-	//}
+    #endregion
 
-	/// <summary>
-	/// 列表页面基础数据
-	/// </summary>
-	/// <returns></returns>
-	[HttpGet("waited/base-data")]
+    #endregion
+
+    #region 工单待办
+
+    ///// <summary>
+    ///// 查询待办工单
+    ///// </summary>
+    //[HttpGet("waited")]
+    //public async Task<PagedDto<OrderDto>> QueryWaited([FromQuery] QueryOrderWaitedDto dto)
+    //{
+    //    var isHandledStep = dto.IsHandled.HasValue && dto.IsHandled.Value;
+    //    if (isHandledStep)
+    //        dto.QueryType = null;
+
+    //    var isAdmin = _orderDomainService.IsCheckAdmin();
+    //    var query = _orderRepository
+    //        .Queryable(hasHandledStep: isHandledStep, isAdmin: isAdmin)
+    //        .Includes(d => d.OrderSpecials);
+    //    if (dto.QueryType is 1 || dto.QueryType is 2)
+    //    {
+    //        query.WhereIF(dto.QueryType is 1, d => d.IsForwarded == false)
+    //            .WhereIF(dto.QueryType is 2, d => d.IsForwarded == true)
+    //            .Where(d => SqlFunc.Subqueryable<OrderSpecial>().Where(os => os.OrderId == d.Id && os.IsDeleted == false && os.SpecialType == ESpecialType.ReTransact)
+    //                .NotAny())
+    //            ;
+    //    }
+
+    //    var (total, items) = await query
+    //        .Where(d => d.Status != EOrderStatus.WaitForAccept &&
+    //                    d.Status != EOrderStatus.BackToUnAccept &&
+    //                    d.Status != EOrderStatus.SpecialToUnAccept &&
+    //                    d.Status != EOrderStatus.HandOverToUnAccept)
+    //        .WhereIF(dto.QueryType is 3,
+    //            d => SqlFunc.Subqueryable<OrderSpecial>().Where(os => os.OrderId == d.Id && os.IsDeleted == false && os.SpecialType == ESpecialType.ReTransact).Any())
+    //        .Where(d => SqlFunc.Subqueryable<OrderDelay>().Where(od => od.OrderId == d.Id && od.IsDeleted == false && od.DelayState == EDelayState.Examining).NotAny())
+    //        .Where(d => SqlFunc.Subqueryable<OrderSendBackAudit>().Where(osba => osba.OrderId == d.Id && osba.IsDeleted == false && osba.State == ESendBackAuditState.Apply)
+    //            .NotAny())
+    //        .Where(d => SqlFunc.Subqueryable<OrderSpecial>().Where(s => s.OrderId == d.Id && s.State == 0 && s.IsDeleted == false).NotAny())
+    //        .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
+    //        .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.StartsWith(dto.Keyword))
+    //        .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No == dto.No)
+    //        .WhereIF(!string.IsNullOrEmpty(dto.AreaCode), d => d.AreaCode == dto.AreaCode)
+    //        .WhereIF(dto.IsCounterSign.HasValue && dto.IsCounterSign == true, d => d.CounterSignType.HasValue)
+    //        .WhereIF(dto.IsCounterSign.HasValue && dto.IsCounterSign == false, d => d.CounterSignType == null)
+    //        .WhereIF(dto.ExpiredOrAlmostOverdue.HasValue && dto.ExpiredOrAlmostOverdue == true,
+    //            d => (d.ExpiredTime < DateTime.Now && d.Status < EOrderStatus.Filed) ||
+    //                 (d.ExpiredTime < d.ActualHandleTime && d.Status >= EOrderStatus.Filed)) //超期 未办
+    //        .WhereIF(dto.ExpiredOrAlmostOverdue.HasValue && dto.ExpiredOrAlmostOverdue == false,
+    //            d => d.NearlyExpiredTime < DateTime.Now && d.ExpiredTime > DateTime.Now) //即将超期 未办
+    //        .Where(d => d.Source < ESource.MLSQ || d.Source > ESource.WZSC)
+    //        .Where(d => d.Status != EOrderStatus.BackToProvince)
+    //        .WhereIF(!isHandledStep || _appOptions.Value.IsYiBin,d=>d.Status < EOrderStatus.Filed)
+    //        //.Where(d => SqlFunc.Subqueryable<OrderSpecial>().Where(os => os.OrderId == d.Id).NotAny())
+    //        //.Where(d => d.OrderSpecials.Any() == false || d.OrderSpecials.Any(s => s.State > 0))
+    //        .WhereIF(dto.StartTime.HasValue, d => d.StartTime >= dto.StartTime)
+    //        .WhereIF(dto.EndTime.HasValue, d => d.StartTime <= dto.EndTime)
+    //        .WhereIF(dto.IsUrgent.HasValue, d => d.IsUrgent == dto.IsUrgent!.Value)
+    //        .WhereIF(dto.Status.HasValue, d => d.Status == dto.Status)
+    //        //.OrderByDescending(d => d.IsUrgent)
+    //        .OrderByIF(string.IsNullOrEmpty(dto.SortField), d => d.StartTime, OrderByType.Desc)
+    //        .OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, d => d.CreationTime, OrderByType.Asc) //创建时间升序
+    //        .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, d => d.CreationTime, OrderByType.Desc) //创建时间降序
+    //        .OrderByIF(dto is { SortField: "startTime", SortRule: 0 }, d => d.StartTime, OrderByType.Asc) //受理时间升序
+    //        .OrderByIF(dto is { SortField: "startTime", SortRule: 1 }, d => d.StartTime, OrderByType.Desc) //受理时间降序
+    //        .OrderByIF(dto is { SortField: "expiredTime", SortRule: 0 }, d => d.ExpiredTime, OrderByType.Asc) //期满时间升序
+    //        .OrderByIF(dto is { SortField: "expiredTime", SortRule: 1 }, d => d.ExpiredTime, OrderByType.Desc) //期满时间降序
+    //        .ToPagedListAsync(dto, HttpContext.RequestAborted);
+
+    //    return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
+    //}
+
+    /// <summary>
+    /// 列表页面基础数据
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet("waited/base-data")]
     public async Task<object> WaitedBaseData()
     {
         var wfModule = await _workflowApplication.GetWorkflowModuleAsync(WorkflowModuleConsts.OrderHandle, HttpContext.RequestAborted);

+ 2 - 0
src/Hotline.Api/Controllers/Snapshot/SnapshotOrderController.cs

@@ -1,6 +1,8 @@
 using Amazon.Runtime.Internal.Transform;
 using Hotline.Application.FlowEngine;
 using Hotline.Application.Snapshot.Contracts;
+using Hotline.Application.Snapshot;
+using Hotline.Application.Snapshot.Contracts;
 using Hotline.Caching.Interfaces;
 using Hotline.Caching.Services;
 using Hotline.Configurations;

+ 2 - 2
src/Hotline.Application/CallCenter/DefaultCallApplication.cs

@@ -339,7 +339,7 @@ public abstract class DefaultCallApplication : ICallApplication
         query = query.WhereIF(dto.Type == 3, (d, o, v) => d.AnsweredTime == null);
         query = query.WhereIF(dto.Type == 1, (d, o, v) => d.Direction == ECallDirection.In && d.AnsweredTime != null);
         query = query.WhereIF(dto.Type == 2, (d, o, v) => d.Direction == ECallDirection.Out && d.AnsweredTime != null);
-        query = query.WhereIF(dto.Type != 3 && !string.IsNullOrEmpty(dto.StaffNo), p => p.StaffNo == dto.StaffNo);
+        query = query.WhereIF(dto.Type != 3 && !string.IsNullOrEmpty(dto.StaffNo), d => d.StaffNo == dto.StaffNo);
 
         if (dto.Type == 2)
         {
@@ -376,7 +376,7 @@ public abstract class DefaultCallApplication : ICallApplication
                         .Max(m => m.TelNo)
                     ),
             }, true)
-                .WhereIF(!string.IsNullOrEmpty(dto.StaffNo), p => p.StaffNo == dto.StaffNo);
+                .WhereIF(!string.IsNullOrEmpty(dto.StaffNo), d => d.StaffNo == dto.StaffNo);
         }
         return query.Select((d, o, v) => new CallNativeDto
         {

+ 27 - 0
src/Hotline.Application/JudicialManagement/EnforcementApplication.cs

@@ -1,10 +1,12 @@
 using Hotline.JudicialManagement;
 using Hotline.Orders;
 using Hotline.Settings;
+using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.JudicialManagement;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Enums.JudicialManagement;
 using Hotline.Share.Enums.Order;
+using Hotline.Snapshot;
 using MapsterMapper;
 using SqlSugar;
 using XF.Domain.Authentications;
@@ -365,5 +367,30 @@ namespace Hotline.Application.JudicialManagement
 
         }
 
+        public async Task<PagedDto<IndustryOrderStaticsDto>> QueryIndustryOrderStatics(QueryIndustryOrderStatisticsRequest queryIndustryOrderStatisticsRequest)
+        {
+            var judicialManagementOrderTable = _judicialManagementOrdersRepository.Queryable()
+                .Where(x => x.CreationTime >= queryIndustryOrderStatisticsRequest.StartTime && x.CreationTime <= queryIndustryOrderStatisticsRequest.EndTime);
+            var queryable = judicialManagementOrderTable.InnerJoin<OrderSnapshot>((j, o) => j.Id == o.Id)
+                .GroupBy((j, o) => o.IndustryName)
+                .Select((j, o) => new IndustryOrderStaticsDto
+                {
+                    IndustryName = o.IndustryName,
+                    TotalOrderCount = SqlFunc.AggregateCount(o.Id),
+                    EnforcementOrderCount = SqlFunc.AggregateCount(SqlFunc.IIF(j.IsEnforcementOrder.HasValue && j.IsEnforcementOrder==true, 1,0)),
+                    NotEnforcementOrderCount = SqlFunc.AggregateCount(SqlFunc.IIF(j.IsEnforcementOrder.HasValue && j.IsEnforcementOrder != true, 1, 0)),
+                    ToBeVerifiedOrderCount = SqlFunc.AggregateCount(SqlFunc.IIF(!j.IsEnforcementOrder.HasValue, 1, 0))
+                });
+
+            var count = await queryable.CountAsync();
+
+            var result = await queryable.ToPageListAsync(queryIndustryOrderStatisticsRequest.PageIndex, queryIndustryOrderStatisticsRequest.PageSize);
+
+            return  new PagedDto<IndustryOrderStaticsDto>
+            {
+                Total = count,
+                Items = result
+            };
+        }
     }
 }

+ 9 - 0
src/Hotline.Application/JudicialManagement/IEnforcementApplication.cs

@@ -1,4 +1,5 @@
 using Hotline.JudicialManagement;
+using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.JudicialManagement;
 using Hotline.Share.Dtos.Order;
 using SqlSugar;
@@ -56,6 +57,8 @@ namespace Hotline.Application.JudicialManagement
         /// <returns></returns>
         ISugarQueryable<JudicialManagementOrders> GetRegionalClassificationStatisticsOrderListAsync(QueryRegionalClassificationStatisticsDto dto);
 
+        
+
         /// <summary>
         /// 部门满意度统计
         /// </summary>
@@ -72,5 +75,11 @@ namespace Hotline.Application.JudicialManagement
         /// <returns></returns>
         ISugarQueryable<EnforcementOrgSatisfactionOrderListDto> GetVisitAndOrgSatisfactionStatisticsOrderListAsync(QueryOrgSatisfactionStatisticsDto dto);
 
+        /// <summary>
+        /// 获取行业订单统计
+        /// </summary>
+        /// <param name="queryIndustryOrderStatisticsRequest"></param>
+        /// <returns></returns>
+        Task<PagedDto<IndustryOrderStaticsDto>> QueryIndustryOrderStatics(QueryIndustryOrderStatisticsRequest queryIndustryOrderStatisticsRequest);
     }
 }

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

@@ -272,6 +272,16 @@ public class OrderMapperConfigs : IRegister
             .Map(d => d.OrgHandledAttitude, s => s.OrgHandledAttitude.Value)
             ;
 
+        config.ForType<OrderVisitDetail, OrderVisitDetailCopy>()
+        .Ignore(d => d.CreationTime)
+         .Ignore(d => d.CreatorId)
+          .Ignore(d => d.CreatorName)
+           .Ignore(d => d.CreatorOrgId)
+            .Ignore(d => d.CreatorOrgLevel)
+            .Ignore(d => d.CreatorOrgName)
+            .Ignore(d => d.AreaId)
+        ;
+
         config.ForType<EarlyWarningSettingDto, EarlyWarningSetting>()
             .IgnoreIf((s, d) => false, d => d.Id);
     }

+ 70 - 8
src/Hotline.Application/OrderApp/OrderApplication.cs

@@ -112,6 +112,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     private readonly ICircularRecordDomainService _circularRecordDomainService;
     private readonly ISessionContextManager _sessionContextManager;
     private readonly IOrderVisitApplication _orderVisitApplication;
+    private readonly IRepository<OrderVisitDetailCopy> _orderVisitDetailCopyRepository;
     private readonly IRepository<OrderEarlyWarning> _orderEarlyWarningRepository;
     private readonly IRepository<EarlyWarningSetting> _earlyWarningSettingRepository;
 
@@ -167,7 +168,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         IOrderVisitApplication orderVisitApplication,
         IRepository<Role> roleRepository,
         IRepository<OrderEarlyWarning> orderEarlyWarningRepository,
-        IRepository<EarlyWarningSetting> earlyWarningSettingRepository)
+        IRepository<EarlyWarningSetting> earlyWarningSettingRepository,
+        IRepository<OrderVisitDetailCopy> orderVisitDetailCopyRepository
+        )
     {
         _orderDomainService = orderDomainService;
         _workflowDomainService = workflowDomainService;
@@ -217,7 +220,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         _circularRecordDomainService = circularRecordDomainService;
         _sessionContextManager = sessionContextManager;
         _orderVisitApplication = orderVisitApplication;
-        _roleRepository = roleRepository;
+        _orderVisitDetailCopyRepository = orderVisitDetailCopyRepository;
         _orderEarlyWarningRepository = orderEarlyWarningRepository;
         _earlyWarningSettingRepository = earlyWarningSettingRepository;
     }
@@ -841,8 +844,14 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .OrderBy(d => new { IsUrgent = d.IsUrgent }, OrderByType.Desc)
             .OrderByIF(string.IsNullOrEmpty(dto.SortField), d => d.IsUrgent, OrderByType.Desc)
             .OrderByIF(string.IsNullOrEmpty(dto.SortField), d => d.FiledTime, OrderByType.Desc)
-			.OrderByIF(dto is { SortRule: 0, SortField: "filedTime" }, d => d.FiledTime, OrderByType.Asc)
-			.OrderByIF(dto is { SortRule: 1, SortField: "filedTime" }, d => d.FiledTime, OrderByType.Desc);
+            .OrderByIF(dto is { SortRule: 0, SortField: "filedTime" }, d => d.FiledTime, OrderByType.Asc)
+            .OrderByIF(dto is { SortRule: 1, SortField: "filedTime" }, d => d.FiledTime, OrderByType.Desc)
+            .OrderByIF(dto is { SortRule: 0, SortField: "actualHandleTime" }, d => d.ActualHandleTime, OrderByType.Asc)
+            .OrderByIF(dto is { SortRule: 1, SortField: "actualHandleTime" }, d => d.ActualHandleTime, OrderByType.Desc)
+            .OrderByIF(dto is { SortRule: 0, SortField: "creationTime" }, d => d.CreationTime, OrderByType.Asc)
+            .OrderByIF(dto is { SortRule: 1, SortField: "creationTime" }, d => d.CreationTime, OrderByType.Desc)
+            .OrderByIF(dto is { SortRule: 0, SortField: "expiredTimeProvince" }, d => d.ExpiredTimeProvince, OrderByType.Asc)
+            .OrderByIF(dto is { SortRule: 1, SortField: "expiredTimeProvince" }, d => d.ExpiredTimeProvince, OrderByType.Desc);
     }
 
     public ISugarQueryable<OrderPublish> GetPublishedOrder(PublishedPagedRequest dto)
@@ -1315,6 +1324,27 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         if (_appOptions.Value.IsYiBin && visit.VisitState == EVisitState.Visited)
             throw UserFriendlyException.SameMessage("已回访,不能重复回访");
 
+        //记录修改历史
+        try
+        {
+            if (dto.IsUpdate.HasValue && dto.IsUpdate == true)
+            {
+                if (visit.OrderVisitDetails != null && visit.OrderVisitDetails.Count > 0)
+                {
+                    var guid = Guid.NewGuid().ToString();
+                    var visitDetailsCopy = _mapper.Map<List<OrderVisitDetailCopy>>(visit.OrderVisitDetails);
+                    foreach (var item in visitDetailsCopy)
+                    {
+                        item.BacthId = guid;
+                    }
+                    await _orderVisitDetailCopyRepository.AddRangeAsync(visitDetailsCopy, cancellationToken);
+                    visit.IsUpdate = true;
+                }
+            }
+        }
+        catch (Exception)
+        { }
+
         var first = dto.VisitDetails.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Org);
 
         visit.IsPutThrough = dto.IsPutThrough;
@@ -1391,6 +1421,37 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             _sessionContext.OrgName);
         await _workflowDomainService.HandleVisitTraceAsync(visit.Id, visitor, visit.VisitTime ?? DateTime.Now, cancellationToken);
 
+        var isOpenSendEndSms = _systemSettingCacheManager.GetSetting(SettingConstants.IsOpenSendEndSms)?.SettingValue[0];
+        if (isOpenSendEndSms == "true")
+        {
+            try
+            {
+                if (_appOptions.Value.IsZiGong)
+                {
+                    if (visit.Order.Source != ESource.ProvinceStraight)
+                    {
+                        //发送查询短信
+                        var messageDto = new Share.Dtos.Push.MessageDto
+                        {
+                            PushBusiness = EPushBusiness.SearchSms,
+                            ExternalId = visit.Id,
+                            OrderId = visit.Order.Id,
+                            PushPlatform = EPushPlatform.Sms,
+                            Remark = visit.Order.Title,
+                            Name = visit.Order.FromName,
+                            TemplateCode = "1021",
+                            Params = new List<string>() { visit.Order.No, visit.Order.Password },
+                            TelNumber = visit.Order.Contact,
+                        };
+                        await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
+                    }
+                }
+            }
+            catch (Exception)
+            {
+            }
+        }
+
         var orderDto = _mapper.Map<OrderDto>(visit.Order);
         if (first != null)
         {
@@ -1427,8 +1488,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         if (first != null)
         {
             //写入质检
-            await _qualityApplication.AddQualityAsync(EQualitySource.Visit, visit.Order.Id, visit.Id,
-                cancellationToken);
+            await _qualityApplication.AddQualityAsync(EQualitySource.Visit, visit.Order.Id, visit.Id, cancellationToken);
 
             if (_appOptions.Value.IsZiGong == true)
             {
@@ -1443,8 +1503,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 }, cancellationToken);
 
                 //回访成功后结果不满意发送甄别提醒短信
-                var isOpenSendEndSms = _systemSettingCacheManager.IsSendDissatisfiedScreenSms;
-                if (isOpenSendEndSms)
+                var isSendDissatisfiedScreenSms = _systemSettingCacheManager.IsSendDissatisfiedScreenSms;
+                if (isSendDissatisfiedScreenSms)
                 {
                     try
                     {
@@ -3631,6 +3691,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .WhereIF(!string.IsNullOrEmpty(dto.OrderTagCode),
                 d => SqlFunc.Subqueryable<OrderRelationTag>().InnerJoin<SystemDicData>((s, p) => s.TagId == p.Id)
                     .Where((s, p) => p.DicDataValue == dto.OrderTagCode && d.OrderId == s.OrderId).Any()) //工单标签
+            .WhereIF(dto.IsUpdate.HasValue && dto.IsUpdate == true, d => d.IsUpdate == true)
+            .WhereIF(dto.IsUpdate.HasValue && dto.IsUpdate == false, d => d.IsUpdate == false || d.IsUpdate == null)
             .OrderByIF(_appOptions.Value.IsYiBin && dto.VisitStateQuery != EVisitStateQuery.Visited, d => d.Order.IsUrgent, OrderByType.Desc)
             .OrderByIF(_appOptions.Value.IsZiGong == false, d => d.PublishTime, OrderByType.Desc)
             //.OrderByDescending(d => d.PublishTime)

+ 15 - 0
src/Hotline.Share/Dtos/File/FileDto.cs

@@ -96,6 +96,21 @@ namespace Hotline.Share.Dtos.File
 			return Classify == "附件列表上传" && userId == CreatorId;
 		}
 
+		/// <summary>
+		/// 创建时间
+		/// </summary>
+		public DateTime? CreationTime { get; set; }
+
+		/// <summary>
+		/// 节点名称
+		/// </summary>
+		public string? StepName { get; set; }
+
+		public string GetStepName(string name) {
+
+			return StepName = name;
+		}
+
 	}
 	public class UpdateFileDto : FileDto
 	{

+ 36 - 1
src/Hotline.Share/Dtos/JudicialManagement/EmDepartmentalProcessingStatisticsDto.cs

@@ -1,4 +1,6 @@
-namespace Hotline.Share.Dtos.JudicialManagement
+using System.ComponentModel;
+
+namespace Hotline.Share.Dtos.JudicialManagement
 {
     public class EmDepartmentalProcessingStatisticsDto
     {
@@ -19,4 +21,37 @@
         public int TheClueIsNotTrue { get; set; }
         public int EnforcementOrder { get; set; }
     }
+
+    public class IndustryOrderStaticsDto
+    {
+        /// <summary>
+        /// 行业名称
+        /// </summary>
+        [Description("行业名称")]
+        public string IndustryName { get; set; }
+
+        /// <summary>
+        /// 办件总量
+        /// </summary>
+        [Description("办件总量")]
+        public int TotalOrderCount { get; set; }
+
+        /// <summary>
+        /// 执法类工单
+        /// </summary>
+        [Description("执法类工单")]
+        public int EnforcementOrderCount { get; set; }
+
+        /// <summary>
+        /// 非执法类工单
+        /// </summary>
+        [Description("非执法类工单")]
+        public int NotEnforcementOrderCount { get; set; }
+
+        /// <summary>
+        /// 待核实订单
+        /// </summary>
+        [Description("待核实订单")]
+        public int ToBeVerifiedOrderCount { get; set; }
+    }
 }

+ 16 - 0
src/Hotline.Share/Dtos/JudicialManagement/QueryEventClassificationStatisticsDto.cs

@@ -1,4 +1,5 @@
 using Hotline.Share.Requests;
+using System.ComponentModel;
 
 namespace Hotline.Share.Dtos.JudicialManagement
 {
@@ -67,6 +68,21 @@ namespace Hotline.Share.Dtos.JudicialManagement
         public bool EnforcementOrder { get; set; }
     }
 
+    public record QueryIndustryOrderStatisticsRequest: PagedRequest
+    {
+        /// <summary>
+        /// 开始时间
+        /// </summary>
+        [Description("开始时间")]
+        public DateTime StartTime { get; set; }
+
+        /// <summary>
+        /// 结束时间
+        /// </summary>
+        [Description("结束时间")]
+        public DateTime EndTime { get; set; }
+    }
+
     /// <summary>
     /// 
     /// </summary>

+ 2 - 1
src/Hotline.Share/Dtos/Order/OrderDto.cs

@@ -1870,9 +1870,10 @@ namespace Hotline.Share.Dtos.Order
         public string? SensitiveText => (Sensitive != null && Sensitive.Any()) ? string.Join(',', Sensitive) : "";
     }
 
-    public class OrderListUploadFilesDto
+    public class OrderStepUploadFilesDto
 	{
 		public string OrderId { get; set; }
+		public string StepId { get; set; }
 		public List<FileDto> Files { get; set; } = new();
 	}
 }

+ 58 - 16
src/Hotline.Share/Dtos/Order/OrderVisitDto.cs

@@ -102,25 +102,25 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public bool? IsOverTime { get; set; }
 
-		/// <summary>
-		/// 发布时间
-		/// </summary>
-		public DateTime? StartPublishTime { get; set; }
+        /// <summary>
+        /// 发布时间
+        /// </summary>
+        public DateTime? StartPublishTime { get; set; }
 
-		/// <summary>
-		/// 发布时间
-		/// </summary>
-		public DateTime? EndPublishTime { get; set; }
+        /// <summary>
+        /// 发布时间
+        /// </summary>
+        public DateTime? EndPublishTime { get; set; }
 
-		/// <summary>
-		/// 接办部门
-		/// </summary>
-		public string? ActualHandleOrgName { get;  set; }
+        /// <summary>
+        /// 接办部门
+        /// </summary>
+        public string? ActualHandleOrgName { get; set; }
 
-		/// <summary>
-		/// 一级部门
-		/// </summary>
-		public string? OrgLevelOneName { get; set; }
+        /// <summary>
+        /// 一级部门
+        /// </summary>
+        public string? OrgLevelOneName { get; set; }
 
         /// <summary>
         /// 来电主体
@@ -148,6 +148,11 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public string? OrderTagCode { get; set; }
 
+        /// <summary>
+        /// 是否回访结果修改
+        /// </summary>
+        public bool? IsUpdate { get; set; }
+
     }
 
     public record QueryOrderPublishStatisticsAllDto : PagedRequest
@@ -465,6 +470,11 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public bool? SeatJudge { get; set; }
 
+        /// <summary>
+        /// 是否回访结果修改
+        /// </summary>
+        public bool? IsUpdate { get; set; }
+
         public List<VisitDetailDto> VisitDetails { get; set; }
     }
 
@@ -860,6 +870,11 @@ namespace Hotline.Share.Dtos.Order
         public string? OrderTagCode { get; set; }
 
         public List<SystemDicDataOutDto>? OrderTags { get; set; }
+
+        /// <summary>
+        /// 是否回访结果修改
+        /// </summary>
+        public bool? IsUpdate { get; set; }
     }
 
     public class OrderVisitDetailDto
@@ -1218,4 +1233,31 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public DateTime PublishTime { get; set; }
     }
+
+    /// <summary>
+    /// 修改记录
+    /// </summary>
+    public class OrderVisitDetailCopyDto
+    {
+        /// <summary>
+        /// 回访信息
+        /// </summary>
+        public List<OrderVisitDetailDto> OrderVisitDetailDtos { get; set; }
+
+        /// <summary>
+        /// 修改记录
+        /// </summary>
+        public List<OrderVisitDetailDto> OrderVisitDetailCopyDtos { get; set; }
+
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public DateTime CreationTime { get; set; }
+
+        /// <summary>
+        /// 创建人
+        /// </summary>
+        public string? CreatorName { get; set; }
+    }
 }

+ 6 - 1
src/Hotline.Share/Enums/Order/ESource.cs

@@ -102,13 +102,18 @@ public enum ESource
     /// <summary>
     /// 宜宾人社APP
     /// </summary>
-    YBHumanSocietyAPP=408,
+    YBHumanSocietyAPP = 408,
 
     /// <summary>
     /// 泸州酒城一通
     /// </summary>
     WineCity = 409,
 
+    /// <summary>
+    /// 泸州市政府门户网站
+    /// </summary>
+    LZCityPortalSite = 410,
+
     #region 导入类型(>=500  <530为导入来源)
     /// <summary>
     /// 麻辣社区导入

+ 1 - 1
src/Hotline.Share/Hotline.Share.csproj

@@ -7,7 +7,7 @@
     <GenerateDocumentationFile>True</GenerateDocumentationFile>
     <NoWarn>$(NoWarn);1591;8618;</NoWarn>
     <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
-    <Version>1.0.119</Version>
+    <Version>1.0.121</Version>
   </PropertyGroup>
 
   <ItemGroup>

+ 9 - 4
src/Hotline.Share/Mq/EventNames.Order.cs

@@ -20,10 +20,15 @@ namespace Hotline.Share.Mq
         /// </summary>
         public const string HotlineOrderFlowHandled = "hotline.order.flow.handled";
 
-        /// <summary>
-        /// 撤回
-        /// </summary>
-        public const string HotlineOrderFlowRecalled = "hotline.order.flow.recalled";
+		/// <summary>
+		/// 补传附件
+		/// </summary>
+		public const string HotlineOrderFlowFile = "hotline.order.flow.file";
+
+		/// <summary>
+		/// 撤回
+		/// </summary>
+		public const string HotlineOrderFlowRecalled = "hotline.order.flow.recalled";
 
         /// <summary>
         /// 退回

+ 2 - 2
src/Hotline/Orders/Order.cs

@@ -911,8 +911,8 @@ namespace Hotline.Orders
         [SugarColumn(ColumnDataType = "json", IsJson = true, IsNullable = true, ColumnDescription = "附件JSON")]
         public List<FileJson>? FileJson { get; set; }
 
-		[SugarColumn(ColumnDataType = "json", IsJson = true, IsNullable = true, ColumnDescription = "附件列表附件JSON")]
-		public List<FileJson>? ListFileJson { get; set; }
+		//[SugarColumn(ColumnDataType = "json", IsJson = true, IsNullable = true, ColumnDescription = "附件列表附件JSON")]
+		//public List<FileJson>? ListFileJson { get; set; }
 
 		#endregion
 

+ 62 - 39
src/Hotline/Orders/OrderDomainService.cs

@@ -340,41 +340,64 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         {
             try
             {
-                if (order.Source != ESource.ProvinceStraight && order.FileOrgIsCenter.Value == false)
+                if (_appOptions.Value.IsZiGong)
                 {
-                    var code = "";
-                    //受理类型为“投诉、举报”
-                    if ((order.AcceptTypeCode == "30" || order.AcceptTypeCode == "35") && orderVisit.VisitState != EVisitState.Visited)
+                    if (order.Source == ESource.ProvinceStraight)
                     {
-                        code = "1017";
-                        orderVisit.VisitState = EVisitState.SMSVisiting;
-                        await _orderVisitRepository.UpdateAsync(orderVisit);
+                        //发送查询短信
+                        var messageDto = new Share.Dtos.Push.MessageDto
+                        {
+                            PushBusiness = EPushBusiness.SearchSms,
+                            ExternalId = visitId,
+                            OrderId = order.Id,
+                            PushPlatform = EPushPlatform.Sms,
+                            Remark = order.Title,
+                            Name = order.FromName,
+                            TemplateCode = "1021",
+                            Params = new List<string>() { order.No, order.Password },
+                            TelNumber = order.Contact,
+                        };
+                        await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
                     }
-                    else
-                        code = "1018";
-
-                    //发送查询短信
-                    var messageDto = new Share.Dtos.Push.MessageDto
+                }
+                else
+                {
+                    if (order.Source != ESource.ProvinceStraight && order.FileOrgIsCenter.Value == false)
                     {
-                        PushBusiness = EPushBusiness.SearchSms,
-                        ExternalId = visitId,
-                        OrderId = order.Id,
-                        PushPlatform = EPushPlatform.Sms,
-                        Remark = order.Title,
-                        Name = order.FromName,
-                        TemplateCode = code,
-                        Params = new List<string>() { order.No, order.Password },
-                        TelNumber = order.Contact,
-                    };
-                    await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
-
-                    // 发送短信后推送一个 48小时的延迟消息队列. 当消息队列收到消息时, 判断用户是否回复了, 如果未回复短信就 默认满意
-                    var delaySecond = _systemSettingCacheManager.DefaultVisitSmsDelaySecond;
-                    await _capPublisher.PublishDelayAsync(
-                        TimeSpan.FromSeconds(delaySecond),
-                        EventNames.UpdateVisitDelaySms,
-                        messageDto,
-                        cancellationToken: cancellationToken);
+                        var code = "";
+                        //受理类型为“投诉、举报”
+                        if ((order.AcceptTypeCode == "30" || order.AcceptTypeCode == "35") && orderVisit.VisitState != EVisitState.Visited)
+                        {
+                            code = "1017";
+                            orderVisit.VisitState = EVisitState.SMSVisiting;
+                            await _orderVisitRepository.UpdateAsync(orderVisit);
+                        }
+                        else
+                            code = "1018";
+
+                        //发送查询短信
+                        var messageDto = new Share.Dtos.Push.MessageDto
+                        {
+                            PushBusiness = EPushBusiness.SearchSms,
+                            ExternalId = visitId,
+                            OrderId = order.Id,
+                            PushPlatform = EPushPlatform.Sms,
+                            Remark = order.Title,
+                            Name = order.FromName,
+                            TemplateCode = code,
+                            Params = new List<string>() { order.No, order.Password },
+                            TelNumber = order.Contact,
+                        };
+                        await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
+
+                        // 发送短信后推送一个 48小时的延迟消息队列. 当消息队列收到消息时, 判断用户是否回复了, 如果未回复短信就 默认满意
+                        var delaySecond = _systemSettingCacheManager.DefaultVisitSmsDelaySecond;
+                        await _capPublisher.PublishDelayAsync(
+                            TimeSpan.FromSeconds(delaySecond),
+                            EventNames.UpdateVisitDelaySms,
+                            messageDto,
+                            cancellationToken: cancellationToken);
+                    }
                 }
             }
             catch (Exception)
@@ -445,7 +468,7 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         if (string.IsNullOrEmpty(orderId))
             throw UserFriendlyException.SameMessage("无效工单编号");
 
-        var query = _orderRepository.Queryable().Includes(d=>d.OrderPushTypes);
+        var query = _orderRepository.Queryable().Includes(d => d.OrderPushTypes);
         if (withHotspot)
             query = query.Includes(d => d.Hotspot);
         if (withAcceptor)
@@ -609,13 +632,13 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
     /// <returns></returns>
     public async Task LogAverageOrder(string userId, Scheduling scheduling, CancellationToken cancellationToken)
     {
-		//1.获取默认派单员所属的工单
-		//2.获取今天上班的人员
-		//3.给当前这个用户平均派单
+        //1.获取默认派单员所属的工单
+        //2.获取今天上班的人员
+        //3.给当前这个用户平均派单
 
-		var steps = await _workflowDomainService.GetStepsBelongsToAsync(AppDefaults.SendPoolId,
-		   cancellationToken);
-		var roleId = _systemSettingCacheManager.GetSetting(SettingConstants.RolePaiDan)?.SettingValue[0];
+        var steps = await _workflowDomainService.GetStepsBelongsToAsync(AppDefaults.SendPoolId,
+           cancellationToken);
+        var roleId = _systemSettingCacheManager.GetSetting(SettingConstants.RolePaiDan)?.SettingValue[0];
 
         var user = await _userRepository.Queryable()
             .Includes(d => d.Organization)
@@ -653,7 +676,7 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
             }, cancellationToken);
         }
 
-	}
+    }
 
     /// <summary>
     /// 触发平均派单

+ 8 - 3
src/Hotline/Orders/OrderVisit.cs

@@ -117,7 +117,7 @@ public class OrderVisit : CreationEntity
     /// <summary>
     /// 智能回访次数
     /// </summary>
-    [SugarColumn( DefaultValue = "0" )]
+    [SugarColumn(DefaultValue = "0")]
     public int AiVisitCount { get; set; }
 
     /// <summary>
@@ -136,11 +136,11 @@ public class OrderVisit : CreationEntity
     /// <summary>
     /// 评判状态
     /// </summary>
-    public EJudgeState? JudgeState { get; set;}
+    public EJudgeState? JudgeState { get; set; }
     /// <summary>
     /// 评判意见
     /// </summary>
-    public string? JudgeContent { get; set;}
+    public string? JudgeContent { get; set; }
 
     /// <summary>
     /// 评判人Id
@@ -167,6 +167,11 @@ public class OrderVisit : CreationEntity
     /// </summary>
     public bool? IsBatchVisit { get; set; }
 
+    /// <summary>
+    /// 是否回访结果修改
+    /// </summary>
+    public bool? IsUpdate { get; set; }
+
     public void AiVisitTime()
     {
         LastVisitTime = DateTime.Now;

+ 19 - 0
src/Hotline/Orders/OrderVisitDetailCopy.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Orders
+{
+    /// <summary>
+    /// 回访历史记录
+    /// </summary>
+    public class OrderVisitDetailCopy : OrderVisitDetail
+    {
+        /// <summary>
+        ///批次Id
+        /// </summary>
+        public string BacthId { get; set; }
+    }
+}

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

@@ -61,6 +61,7 @@ public class DefaultCallApplicationTest : TestBase
         var inDto = new QueryCallsFixedDto();
         inDto.CallStartTimeEnd = DateTime.Now;
         inDto.CallStartTimeStart = "2024/10/01 00:00:00".ObjToDate();
+        inDto.StaffNo = "8029";
 
         var items = await _defaultCallApplication.QueryCallsFixedAsync(inDto, new CancellationToken()).ToPageListWithoutTotalAsync(inDto, CancellationToken.None);
         items.ShouldNotBeNull();