Prechádzať zdrojové kódy

Merge branch 'dev' into dev_dss

Dun.Jason 11 mesiacov pred
rodič
commit
bbfe45a1cd

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

@@ -1551,7 +1551,7 @@ namespace Hotline.Api.Controllers.Bi
                          .Select(it => new DepartmentalProcessingStatisticsDataDto
                          {
                              OrgCode = it.OrgCode,
-                            // OrderCountNum = SqlFunc.AggregateCount(it.OrgCode),//总量
+                             // OrderCountNum = SqlFunc.AggregateCount(it.OrgCode),//总量
                              YBOrderCountNum = SqlFunc.AggregateSum(SqlFunc.IIF(it.Status >= EOrderStatus.Filed, 1, 0)),//已办// SqlFunc.AggregateSum(SqlFunc.IIF(it.Status >= EOrderStatus.Filed, 1, 0)),//已办
                              ZBOrderCountNum = SqlFunc.AggregateSum(SqlFunc.IIF(it.Status < EOrderStatus.Filed, 1, 0)),//在办
                              Archived = SqlFunc.AggregateSum(SqlFunc.IIF(it.Status >= EOrderStatus.Filed, 1, 0)),//已归档
@@ -1595,7 +1595,7 @@ namespace Hotline.Api.Controllers.Bi
                 .Select(it => new DepartmentalProcessingStatisticsDataDto
                 {
                     OrgCode = it.OrgCode,
-                  //  OrderCountNum = 0,//总量
+                    //  OrderCountNum = 0,//总量
                     YBOrderCountNum = 0,//已办
                     ZBOrderCountNum = 0,//在办
                     Archived = 0,
@@ -1681,7 +1681,7 @@ namespace Hotline.Api.Controllers.Bi
                 .Select(x => new DepartmentalProcessingStatisticsDataDto
                 {
                     OrgCode = x.OrgCode,
-                  //  OrderCountNum = 0,//总量
+                    //  OrderCountNum = 0,//总量
                     YBOrderCountNum = 0,//已办
                     ZBOrderCountNum = 0,//在办
                     Archived = 0,
@@ -1724,7 +1724,7 @@ namespace Hotline.Api.Controllers.Bi
                 .Select(x => new DepartmentalProcessingStatisticsDataDto
                 {
                     OrgCode = x.OrgCode,
-                   // OrderCountNum = 0,//总量
+                    // OrderCountNum = 0,//总量
                     YBOrderCountNum = 0,//已办
                     ZBOrderCountNum = 0,//在办
                     Archived = 0,
@@ -1765,7 +1765,7 @@ namespace Hotline.Api.Controllers.Bi
             .Select(x => new DepartmentalProcessingStatisticsDataDto
             {
                 OrgCode = x.OrgCode,
-              //  OrderCountNum = 0,//总量
+                //  OrderCountNum = 0,//总量
                 YBOrderCountNum = 0,//已办
                 ZBOrderCountNum = 0,//在办
                 Archived = 0,
@@ -1831,7 +1831,7 @@ namespace Hotline.Api.Controllers.Bi
                 OrgCode = "",
                 OrgName = "合计",
                 OrgType = EOrgType.City,
-               // OrderCountNum = items.Sum(p => p.OrderCountNum),
+                // OrderCountNum = items.Sum(p => p.OrderCountNum),
                 YBOrderCountNum = items.Sum(p => p.YBOrderCountNum),
                 ZBOrderCountNum = items.Sum(p => p.ZBOrderCountNum),
                 Archived = items.Sum(p => p.Archived),
@@ -1894,7 +1894,7 @@ namespace Hotline.Api.Controllers.Bi
                       .Select(it => new DepartmentalProcessingStatisticsDataDto
                       {
                           OrgCode = it.OrgCode,
-                        //  OrderCountNum = SqlFunc.AggregateCount(it.OrgCode),//总量
+                          //  OrderCountNum = SqlFunc.AggregateCount(it.OrgCode),//总量
                           YBOrderCountNum = SqlFunc.AggregateSum(SqlFunc.IIF(it.Status >= EOrderStatus.Filed, 1, 0)),//已办
                           ZBOrderCountNum = SqlFunc.AggregateSum(SqlFunc.IIF(it.Status < EOrderStatus.Filed, 1, 0)),//在办
                           Archived = SqlFunc.AggregateSum(SqlFunc.IIF(it.Status >= EOrderStatus.Filed, 1, 0)),//已归档
@@ -1939,7 +1939,7 @@ namespace Hotline.Api.Controllers.Bi
                 .Select(it => new DepartmentalProcessingStatisticsDataDto
                 {
                     OrgCode = it.OrgCode,
-                   // OrderCountNum = 0,//总量
+                    // OrderCountNum = 0,//总量
                     YBOrderCountNum = 0,//已办
                     ZBOrderCountNum = 0,//在办
                     Archived = 0,
@@ -1985,7 +1985,7 @@ namespace Hotline.Api.Controllers.Bi
              .Select(d => new DepartmentalProcessingStatisticsDataDto
              {
                  OrgCode = d.OrgCode,
-                // OrderCountNum = 0,//总量
+                 // OrderCountNum = 0,//总量
                  YBOrderCountNum = 0,//已办
                  ZBOrderCountNum = 0,//在办
                  Archived = 0,
@@ -1996,10 +1996,10 @@ namespace Hotline.Api.Controllers.Bi
                  YBOverdue = 0,
                  ZBOverdue = 0,
                  CompleteOnTime = 0,
-                 HQYBOverdue = SqlFunc.AggregateSum(SqlFunc.IIF(d.Status == EWorkflowStepStatus.Handled && d.HandleTime > d.StepExpiredTime, 1, 0)),
-                 HQZBOverdue = SqlFunc.AggregateSum(SqlFunc.IIF(d.Status != EWorkflowStepStatus.Handled && DateTime.Now >= d.StepExpiredTime, 1, 0)),
-                 DelayEnd = SqlFunc.AggregateSum(SqlFunc.IIF(d.Status == EWorkflowStepStatus.Handled, 1, 0)),
-                 DelayWait = SqlFunc.AggregateSum(SqlFunc.IIF(d.Status != EWorkflowStepStatus.Handled, 1, 0)),
+                 HQYBOverdue = SqlFunc.AggregateSum(SqlFunc.IIF(d.Status >= EWorkflowStepStatus.Handled && d.HandleTime > d.StepExpiredTime, 1, 0)),
+                 HQZBOverdue = SqlFunc.AggregateSum(SqlFunc.IIF(d.Status < EWorkflowStepStatus.Handled && DateTime.Now >= d.StepExpiredTime, 1, 0)),
+                 DelayEnd = SqlFunc.AggregateSum(SqlFunc.IIF(d.Status >= EWorkflowStepStatus.Handled, 1, 0)),
+                 DelayWait = SqlFunc.AggregateSum(SqlFunc.IIF(d.Status < EWorkflowStepStatus.Handled, 1, 0)),
                  OrderDelayCount = 0,
                  ScreenCount = 0,
                  ScreenApproval = 0,
@@ -2027,7 +2027,7 @@ namespace Hotline.Api.Controllers.Bi
                 .Select(x => new DepartmentalProcessingStatisticsDataDto
                 {
                     OrgCode = x.OrgCode,
-                  //  OrderCountNum = 0,//总量
+                    //  OrderCountNum = 0,//总量
                     YBOrderCountNum = 0,//已办
                     ZBOrderCountNum = 0,//在办
                     Archived = 0,
@@ -2071,7 +2071,7 @@ namespace Hotline.Api.Controllers.Bi
                 .Select(x => new DepartmentalProcessingStatisticsDataDto
                 {
                     OrgCode = x.OrgCode,
-                  //  OrderCountNum = 0,//总量
+                    //  OrderCountNum = 0,//总量
                     YBOrderCountNum = 0,//已办
                     ZBOrderCountNum = 0,//在办
                     Archived = 0,
@@ -2113,7 +2113,7 @@ namespace Hotline.Api.Controllers.Bi
             .Select(x => new DepartmentalProcessingStatisticsDataDto
             {
                 OrgCode = x.OrgCode,
-               // OrderCountNum = 0,//总量
+                // OrderCountNum = 0,//总量
                 YBOrderCountNum = 0,//已办
                 ZBOrderCountNum = 0,//在办
                 Archived = 0,
@@ -2180,7 +2180,7 @@ namespace Hotline.Api.Controllers.Bi
                 OrgCode = "",
                 OrgName = "合计",
                 OrgType = EOrgType.City,
-               // OrderCountNum = items.Sum(p => p.OrderCountNum),
+                // OrderCountNum = items.Sum(p => p.OrderCountNum),
                 YBOrderCountNum = items.Sum(p => p.YBOrderCountNum),
                 ZBOrderCountNum = items.Sum(p => p.ZBOrderCountNum),
                 Archived = items.Sum(p => p.Archived),

+ 193 - 9
src/Hotline.Api/Controllers/OrderController.cs

@@ -111,8 +111,9 @@ public class OrderController : BaseController
     private readonly IExportApplication _exportApplication;
     private readonly IRepository<TranspondCityRawData> _transpondCityRawDataRepository;
     private readonly IRepository<OrderSpecialDetail> _orderSpecialDetailRepository;
+    private readonly IOrderSecondaryHandlingApplication _orderSecondaryHandlingApplication;
 
-    public OrderController(
+	public OrderController(
         IOrderDomainService orderDomainService,
         IOrderRepository orderRepository,
         IWorkflowApplication workflowApplication,
@@ -162,8 +163,9 @@ public class OrderController : BaseController
         IRepository<User> userRepository,
         IExportApplication exportApplication,
         IRepository<TranspondCityRawData> transpondCityRawDataRepository,
-        IRepository<OrderSpecialDetail> orderSpecialDetailRepository
-        )
+        IRepository<OrderSpecialDetail> orderSpecialDetailRepository,
+	    IOrderSecondaryHandlingApplication orderSecondaryHandlingApplication
+		)
     {
         _orderDomainService = orderDomainService;
         _orderRepository = orderRepository;
@@ -215,7 +217,8 @@ public class OrderController : BaseController
         _exportApplication = exportApplication;
         _transpondCityRawDataRepository = transpondCityRawDataRepository;
         _orderSpecialDetailRepository = orderSpecialDetailRepository;
-    }
+        _orderSecondaryHandlingApplication = orderSecondaryHandlingApplication;
+	}
 
     #region 工单发布
 
@@ -3611,9 +3614,7 @@ public class OrderController : BaseController
             await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto, cancellationToken: HttpContext.RequestAborted);
             //}
 
-            //todo 特提重办,按审批通过时间依据中心派至部门的规则计算期满时间,更新order
-
-            await _workflowApplication.RecallAsync(recall, expiredTime.ExpiredTime, HttpContext.RequestAborted);
+			await _workflowApplication.RecallAsync(recall, expiredTime.ExpiredTime, HttpContext.RequestAborted);
             var publish = await _orderPublishRepository.GetAsync(x => x.OrderId == special.OrderId);
             if (publish != null)
             {
@@ -3707,7 +3708,6 @@ public class OrderController : BaseController
                 await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto, cancellationToken: HttpContext.RequestAborted);
                 //}
 
-                //todo 特提重办,按审批通过时间依据中心派至部门的规则计算期满时间,更新order
 
                 await _workflowApplication.RecallAsync(recall, expiredTime.ExpiredTime, HttpContext.RequestAborted);
                 var publish = await _orderPublishRepository.GetAsync(x => x.OrderId == special.OrderId);
@@ -4697,5 +4697,189 @@ public class OrderController : BaseController
         };
         return rsp;
     }
-    #endregion
+	#endregion
+
+	#region  二次办理
+
+	/// <summary>
+	/// 新增二次办理
+	/// </summary>
+	/// <param name="dtos"></param>
+	/// <returns></returns>
+	[HttpPost("secondary_handling")]
+	[LogFilter("新增二次办理")]
+	public async Task OrderSecondaryHandlingAdd([FromBody] AddOrderSecondaryHandlingDto dto)
+	{
+        await _orderSecondaryHandlingApplication.AddAsync(dto, HttpContext.RequestAborted);
+	}
+
+
+	/// <summary>
+	/// 二次办理退回
+	/// </summary>
+	/// <param name="dtos"></param>
+	/// <returns></returns>
+	[HttpPost("secondary_handling/send_back")]
+	[LogFilter("二次办理退回")]
+	public async Task OrderSecondaryHandlingSendBackAsync([FromBody] SendBackOrderSecondaryHandlingDto dto)
+	{
+		await _orderSecondaryHandlingApplication.SendBackAsync(dto, HttpContext.RequestAborted);
+	}
+
+	/// <summary>
+	/// 二次办理审批
+	/// </summary>
+	/// <param name="dtos"></param>
+	/// <returns></returns>
+	[HttpPut("secondary_handling/audit")]
+	[LogFilter("二次办理审批")]
+	public async Task OrderSecondaryHandlingAudit([FromBody]  AuditOrderSecondaryHandlingDto dto)
+	{
+        var model = await _orderSecondaryHandlingApplication.Entity(dto.Id, HttpContext.RequestAborted);
+        if (model == null || model.State != ESecondaryHandlingState.Apply)
+            throw UserFriendlyException.SameMessage("无效特提审批信息!");
+        await _orderSecondaryHandlingApplication.AuditAsync(dto, model, HttpContext.RequestAborted);
+	}
+
+	/// <summary>
+	/// 二次办理批量审批
+	/// </summary>
+	/// <param name="dtos"></param>
+	/// <returns></returns>
+	[HttpPut("secondary_handling/batch_audit")]
+	[LogFilter("二次办理批量审批")]
+	public async Task OrderSecondaryHandlingBatchAudit([FromBody] AuditOrderSecondaryHandlingDto dto)
+	{
+		foreach (var item in dto.Ids)
+		{
+			var model = await _orderSecondaryHandlingApplication.Entity(item, HttpContext.RequestAborted);
+			if (model == null || model.State != ESecondaryHandlingState.Apply)
+				throw UserFriendlyException.SameMessage("无效特提审批信息!");
+			await _orderSecondaryHandlingApplication.AuditAsync(dto, model, HttpContext.RequestAborted);
+		}
+	}
+
+
+	/// <summary>
+	/// 二次办理申请列表
+	/// </summary>
+	/// <returns></returns>
+	[HttpGet("secondary_handling/apply")]
+	public async Task<PagedDto<OrderVisitDetailDto>> OrderSecondaryHandlingApplyQuery([FromQuery] MayScreenListDto dto)
+	{
+		var query = _orderSecondaryHandlingApplication.ApplyQuery(dto, HttpContext.RequestAborted);
+		var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
+
+		return new PagedDto<OrderVisitDetailDto>(total, _mapper.Map<IReadOnlyList<OrderVisitDetailDto>>(items));
+	}
+
+    /// <summary>
+    /// 二次办理申请列表导出
+    /// </summary>
+    /// <returns></returns>
+	[HttpPost("secondary_handling/apply_export")]
+	public async Task<FileStreamResult> OrderSecondaryHandlingApplyExport([FromBody] ExportExcelDto<MayScreenListDto> dto)
+	{
+		var query = _orderSecondaryHandlingApplication.ApplyQuery(dto.QueryDto, HttpContext.RequestAborted);
+		List<OrderVisitDetail> visitDetails;
+		if (dto.IsExportAll)
+		{
+			visitDetails = await query.ToListAsync(HttpContext.RequestAborted);
+		}
+		else
+		{
+			var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+			visitDetails = items;
+		}
+
+		var visitDetailsDtos = _mapper.Map<ICollection<OrderVisitDetailDto>>(visitDetails);
+
+		dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+		var dtos = visitDetailsDtos
+			.Select(stu => _mapper.Map(stu, typeof(OrderVisitDetailDto), dynamicClass))
+			.Cast<object>()
+			.ToList();
+
+		var stream = ExcelHelper.CreateStream(dtos);
+
+		return ExcelStreamResult(stream, "二次办理申请列表数据");
+	}
+
+    /// <summary>
+    /// 二次办理列表
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet("secondary_handling")]
+    public async Task<PagedDto<OrderSecondaryHandlingDto>> OrderSecondaryHandlingQuery([FromQuery] SecondaryHandlingListDto dto)
+    {
+	    var query = _orderSecondaryHandlingApplication.Query(dto, HttpContext.RequestAborted);
+	    var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
+
+	    return new PagedDto<OrderSecondaryHandlingDto>(total, _mapper.Map<IReadOnlyList<OrderSecondaryHandlingDto>>(items));
+    }
+
+    /// <summary>
+    /// 二次办理列表导出
+    /// </summary>
+    /// <returns></returns>
+    [HttpPost("secondary_handling/_export")]
+    public async Task<FileStreamResult> OrderSecondaryHandlingExport([FromBody] ExportExcelDto<SecondaryHandlingListDto> dto)
+    {
+	    var query = _orderSecondaryHandlingApplication.Query(dto.QueryDto, HttpContext.RequestAborted);
+	    List<OrderSecondaryHandling> secondaryHandling;
+	    if (dto.IsExportAll)
+	    {
+		    secondaryHandling = await query.ToListAsync(HttpContext.RequestAborted);
+	    }
+	    else
+	    {
+		    var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
+		    secondaryHandling = items;
+	    }
+
+	    var secondaryHandlingDtos = _mapper.Map<ICollection<OrderVisitDetailDto>>(secondaryHandling);
+
+	    dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass(dto.ColumnInfos);
+
+	    var dtos = secondaryHandlingDtos
+			.Select(stu => _mapper.Map(stu, typeof(OrderSecondaryHandlingDto), dynamicClass))
+		    .Cast<object>()
+		    .ToList();
+
+	    var stream = ExcelHelper.CreateStream(dtos);
+
+	    return ExcelStreamResult(stream, "二次办理列表数据");
+    }
+
+	/// <summary>
+	/// 获取实体
+	/// </summary>
+	/// <param name="id"></param>
+	/// <returns></returns>
+	[HttpGet("secondary_handling/{id}")]
+	public async Task<OrderSecondaryHandling> OrderSecondaryHandlingEntity(string id)
+	{
+        return await _orderSecondaryHandlingApplication.Entity(id, HttpContext.RequestAborted);
+	}
+
+	/// <summary>
+	/// 列表页面基础数据
+	/// </summary>
+	/// <returns></returns>
+	[HttpGet("secondary_handling/base")]
+	public async Task<object> SecondaryHandlingBaseData()
+	{
+		var rsp = new
+		{
+			Status = EnumExts.GetDescriptions<ESecondaryHandlingState>(),
+			CounterSignType = EnumExts.GetDescriptions<ECounterSignType>(),
+			AcceptType = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType),
+			SourceChannel = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.SourceChannel),
+			VisitSatisfaction = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.VisitSatisfaction),
+			DissatisfiedReason = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.DissatisfiedReason),
+		};
+		return rsp;
+	}
+	#endregion
 }

+ 1 - 0
src/Hotline.Application/Mappers/IdentityMapperConfigs.cs

@@ -21,6 +21,7 @@ public class IdentityMapperConfigs : IRegister
         config.NewConfig<User, UserDto>()
             .IgnoreIf((s, d) => s.Account == null, d => d.UserName)
             .IgnoreIf((s, d) => s.Roles == null || !s.Roles.Any(), d => d.RoleNames)
+            .IgnoreIf((s, d) => s.Organization == null, d => d.Organization)
             .Map(d => d.UserName, x => x.Account.UserName)
             .Map(d => d.State, x => x.IsDeleted ? "已删除" : "正常")
             .Map(d => d.RoleNames, x => string.Join(',', x.Roles.Select(s => s.DisplayName)))

+ 22 - 0
src/Hotline.Application/Orders/IOrderSecondaryHandlingApplication.cs

@@ -0,0 +1,22 @@
+using Hotline.Orders;
+using Hotline.Share.Dtos.Order;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Application.Orders
+{
+	public interface IOrderSecondaryHandlingApplication
+	{
+		Task AddAsync(AddOrderSecondaryHandlingDto dto, CancellationToken cancellationToken);
+
+		Task SendBackAsync(SendBackOrderSecondaryHandlingDto dto, CancellationToken cancellationToken);
+		Task AuditAsync(AuditOrderSecondaryHandlingDto dto, OrderSecondaryHandling model, CancellationToken cancellationToken);
+		ISugarQueryable<OrderVisitDetail> ApplyQuery(MayScreenListDto dto, CancellationToken cancellationToken);
+		Task<OrderSecondaryHandling> Entity(string id, CancellationToken cancellationToken);
+		ISugarQueryable<OrderSecondaryHandling> Query(SecondaryHandlingListDto dto, CancellationToken cancellationToken);
+	}
+}

+ 287 - 0
src/Hotline.Application/Orders/OrderSecondaryHandlingApplication.cs

@@ -0,0 +1,287 @@
+using DotNetCore.CAP;
+using Hotline.Application.FlowEngine;
+using Hotline.File;
+using Hotline.FlowEngine.Workflows;
+using Hotline.Orders;
+using Hotline.Repository.SqlSugar.Orders;
+using Hotline.Settings.TimeLimits;
+using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.FlowEngine;
+using Hotline.Share.Dtos.Order;
+using Hotline.Share.Enums.Order;
+using MapsterMapper;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using SqlSugar;
+using System.Threading;
+using Hotline.Repository.SqlSugar.Extensions;
+using XF.Domain.Authentications;
+using XF.Domain.Dependency;
+using XF.Domain.Exceptions;
+using XF.Domain.Repository;
+
+namespace Hotline.Application.Orders
+{
+	public class OrderSecondaryHandlingApplication : IOrderSecondaryHandlingApplication, IScopeDependency
+	{
+		private readonly IMapper _mapper;
+		private readonly IRepository<OrderSecondaryHandling> _orderSecondaryHandlingRepository;
+		private readonly IFileRepository _fileRepository;
+		private readonly IRepository<OrderVisit> _orderVisitRepository;
+		private readonly ISessionContext _sessionContext;
+		private readonly IOrderRepository _orderRepository;
+		private readonly ITimeLimitDomainService _timeLimitDomainService;
+		private readonly ICapPublisher _capPublisher;
+		private readonly IWorkflowApplication _workflowApplication;
+		private readonly IRepository<OrderPublish> _orderPublishRepository;
+		private readonly IRepository<OrderPublishHistory> _orderPublishHistoryRepository;
+		private readonly IWorkflowDomainService _workflowDomainService;
+		private readonly IRepository<OrderVisitDetail> _orderVisitedDetailRepository;
+
+		public OrderSecondaryHandlingApplication(
+			IMapper mapper,
+			IRepository<OrderSecondaryHandling> orderSecondaryHandlingRepository,
+			IFileRepository fileRepository,
+			IRepository<OrderVisit> orderVisitRepository,
+			ISessionContext sessionContext,
+			IOrderRepository orderRepository,
+			ITimeLimitDomainService timeLimitDomainService,
+			ICapPublisher capPublisher,
+			IWorkflowApplication workflowApplication,
+			IRepository<OrderPublish> orderPublishRepository,
+			IRepository<OrderPublishHistory> orderPublishHistoryRepository,
+			IWorkflowDomainService workflowDomainService,
+			IRepository<OrderVisitDetail> orderVisitedDetailRepository
+			) {
+			_mapper = mapper;
+			_orderSecondaryHandlingRepository = orderSecondaryHandlingRepository;
+			_fileRepository = fileRepository;
+			_orderVisitRepository = orderVisitRepository;
+			_sessionContext = sessionContext;
+			_orderRepository = orderRepository;
+			_timeLimitDomainService = timeLimitDomainService;
+			_capPublisher = capPublisher;
+			_workflowApplication = workflowApplication;
+			_orderPublishRepository = orderPublishRepository;
+			_orderPublishHistoryRepository = orderPublishHistoryRepository;
+			_workflowDomainService = workflowDomainService;
+			_orderVisitedDetailRepository = orderVisitedDetailRepository;
+		}
+
+		/// <summary>
+		///  二次办理新增
+		/// </summary>
+		/// <returns></returns>
+		public async Task AddAsync(AddOrderSecondaryHandlingDto dto, CancellationToken cancellationToken)
+		{
+			var model = _mapper.Map<OrderSecondaryHandling>(dto);
+			if (string.IsNullOrEmpty(dto.Id))
+			{
+				model.InitId();
+			}
+			else {
+				model = await _orderSecondaryHandlingRepository.GetAsync(dto.Id , cancellationToken);
+				model.Content = dto.Content;
+			}
+			model.State = ESecondaryHandlingState.Apply;
+			model.ApplyOrgId = _sessionContext.OrgId;
+			model.ApplyOrgName = _sessionContext.OrgName;
+		
+			if (dto.Files.Any())
+				model.FileJson = await _fileRepository.AddFileAsync(dto.Files, model.Id, "", cancellationToken);
+
+			var visit = await _orderVisitRepository.GetAsync(x => x.Id  == dto.VisitId && x.VisitState != EVisitState.None, cancellationToken);
+			if (visit != null)
+			{
+				model.VisitState = visit.VisitState;
+				visit.VisitState = EVisitState.None;
+				await _orderVisitRepository.UpdateAsync(visit, cancellationToken);
+			}
+
+			if (!string.IsNullOrEmpty(dto.Id))
+			{
+				await _orderSecondaryHandlingRepository.UpdateAsync(model, cancellationToken);
+			}
+			else {
+				await _orderSecondaryHandlingRepository.AddAsync(model, cancellationToken);
+			}
+		}
+
+		public async Task SendBackAsync(SendBackOrderSecondaryHandlingDto dto, CancellationToken cancellationToken) 
+		{
+			var model =await _orderSecondaryHandlingRepository.GetAsync(dto.Id, cancellationToken);
+			model.State = ESecondaryHandlingState.NotApply;
+			model.SendBackContent = dto.SendBackContent;
+			await _orderSecondaryHandlingRepository.UpdateAsync(model, cancellationToken);
+			var visit = await _orderVisitRepository.GetAsync(x => x.Id == model.VisitId , cancellationToken);
+			if (visit != null)
+			{
+				visit.VisitState = model.VisitState;
+				await _orderVisitRepository.UpdateAsync(visit, cancellationToken);
+			}
+		}
+
+
+		/// <summary>
+		/// 二次办理审批
+		/// </summary>
+		/// <returns></returns>
+		public async Task AuditAsync(AuditOrderSecondaryHandlingDto dto, OrderSecondaryHandling model, CancellationToken cancellationToken)
+		{
+
+			model.State = dto.State;
+			model.AuditContent = dto.AuditContent;
+			model.AuditId = _sessionContext.UserId;
+			model.AuditUser = _sessionContext.UserName;
+			model.AuditTime = DateTime.Now;
+			if (model.State == ESecondaryHandlingState.End)
+			{
+				var order = await _orderRepository.GetAsync(x => x.Id == model.OrderId, cancellationToken);
+				if (string.IsNullOrEmpty(order.WorkflowId))
+					throw UserFriendlyException.SameMessage("无效二次办理审批信息,没有找到对应流程信息!");
+				var step = await _workflowDomainService.FindLastHandleStepAsync(order.WorkflowId, model.ApplyOrgId, cancellationToken);
+				if (step == null)
+					throw UserFriendlyException.SameMessage("无效二次办理审批信息,没有找到对应流程节点!");
+				var recall = new RecallDto
+				{
+					WorkflowId = order.WorkflowId!,
+					NextStepCode = step.Code,
+					NextStepName = step.Name,
+					NextHandlers = step.Handlers,
+					Opinion = dto.AuditContent,
+					FlowDirection = Share.Enums.FlowEngine.EFlowDirection.CenterToOrg,
+					HandlerType = step.HandlerType,
+					BusinessType = step.BusinessType
+				};
+				var expiredTime = _timeLimitDomainService.CalcEndTime(DateTime.Now, order.AcceptTypeCode);
+				await _orderRepository.Updateable().SetColumns(o => new Order() { ExpiredTime = expiredTime.ExpiredTime, NearlyExpiredTime = expiredTime.NearlyExpiredTime })
+					.Where(o => o.Id == order.Id).ExecuteCommandAsync(cancellationToken);
+				var orderDto = _mapper.Map<OrderDto>(order);
+				await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto, cancellationToken: cancellationToken);
+
+				await _workflowApplication.RecallAsync(recall, expiredTime.ExpiredTime, cancellationToken);
+				var publish = await _orderPublishRepository.GetAsync(x => x.OrderId == model.OrderId);
+				if (publish != null)
+				{
+					var publishHistory = _mapper.Map<OrderPublishHistory>(publish);
+					publishHistory.OrderPublishId = publish.Id;
+					publishHistory.ArrangeTitleAfter = publish.ArrangeTitle;
+					publishHistory.ArrangeTitleBefor = publish.ArrangeTitle;
+					publishHistory.ArrangeContentAfter = publish.ArrangeContent;
+					publishHistory.ArrangeContentBefor = publish.ArrangeContent;
+					publishHistory.ArrangeOpinionAfter = publish.ArrangeOpinion;
+					publishHistory.ArrangeOpinionBefor = publish.ArrangeOpinion;
+					await _orderPublishHistoryRepository.AddAsync(publishHistory, cancellationToken);
+					await _orderPublishRepository.RemoveAsync(publish, false, cancellationToken);
+				}
+			}
+			else {
+				var visit = await _orderVisitRepository.GetAsync(x => x.OrderId == model.OrderId, cancellationToken);
+				visit.VisitState = model.VisitState;
+				await _orderVisitRepository.UpdateAsync(visit, cancellationToken);
+			}
+			await _orderSecondaryHandlingRepository.UpdateAsync(model, cancellationToken);
+		}
+
+
+		/// <summary>
+		/// 获取申请列表
+		/// </summary>
+		/// <returns></returns>
+		public ISugarQueryable<OrderVisitDetail> ApplyQuery(MayScreenListDto dto, CancellationToken cancellationToken)
+		{
+			dto.CreationTimeEnd = DateTime.Now;
+			dto.CreationTimeStart = DateTime.Now;
+			if (dto.IsHomePage != null && dto.IsHomePage == true)
+			{
+				dto.CreationTimeStart = _timeLimitDomainService.CalcWorkTimeReduce(DateTime.Now, 5);
+			}
+
+			var query = _orderVisitedDetailRepository.Queryable(false, true)
+				.Includes(x => x.OrderVisit)
+				.Includes(x => x.OrderVisit, y => y.Order)
+				.Includes(x => x.OrderVisit, y => y.Employee)
+				.Includes(x=>x.SecondaryHandling)
+				.LeftJoin<OrderScreen>((x, s) => x.Id == s.VisitDetailId && s.Status <  EScreenStatus.End && s.IsDeleted == false)
+				.Where((x, s) => s.Id == null && (x.SecondaryHandling.State == ESecondaryHandlingState.NotApply || x.SecondaryHandling.Id == null))
+				.WhereIF(dto.IsHomePage.HasValue && dto.IsHomePage == true, x => x.OrderVisit.VisitTime < dto.CreationTimeEnd && x.OrderVisit.VisitTime > dto.CreationTimeStart)
+				.WhereIF(!string.IsNullOrEmpty(dto.No), x => x.OrderVisit.Order!.No!.Contains(dto.No!))
+				.WhereIF(dto.IsProvince.HasValue, x => x.OrderVisit.Order!.IsProvince == dto.IsProvince)
+				.WhereIF(!string.IsNullOrEmpty(dto.Title), x => x.OrderVisit.Order!.Title!.Contains(dto.Title!))
+				.WhereIF(!string.IsNullOrEmpty(dto.SourceChannel), x => x.OrderVisit.Order!.SourceChannelCode! == dto.SourceChannel!)
+				.WhereIF(!string.IsNullOrEmpty(dto.AcceptType), x => x.OrderVisit.Order!.AcceptTypeCode! == dto.AcceptType!)
+				.WhereIF(dto.CounterSignType.HasValue, x => x.OrderVisit.Order!.CounterSignType == dto.CounterSignType)
+				.WhereIF(!string.IsNullOrEmpty(dto.OrgLevelOneName), x => x.OrderVisit.Order!.OrgLevelOneName!.Contains(dto.OrgLevelOneName!))
+				.WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), x => x.OrderVisit.Order!.ActualHandleOrgName!.Contains(dto.ActualHandleOrgName!))
+				.WhereIF(dto.ActualHandleTime.HasValue && dto.EndActualHandleTime.HasValue, x => x.OrderVisit.Order!.ActualHandleTime >= dto.ActualHandleTime && x.OrderVisit.Order!.ActualHandleTime <= dto.EndActualHandleTime)
+				.WhereIF(dto.FiledTime.HasValue && dto.EndFiledTime.HasValue, x => x.OrderVisit.Order!.FiledTime == dto.FiledTime && x.OrderVisit.Order!.FiledTime <= dto.EndFiledTime)
+				.WhereIF(dto.CreationTime.HasValue && dto.EndCreationTime.HasValue, x => x.OrderVisit.Order!.CreationTime == dto.CreationTime && x.OrderVisit.Order!.CreationTime <= dto.EndCreationTime)
+				.WhereIF(dto.VisitTime.HasValue && dto.EndVisitTime.HasValue, x => x.OrderVisit.VisitTime == dto.VisitTime && x.OrderVisit.VisitTime <= dto.EndVisitTime)
+				.WhereIF(!string.IsNullOrEmpty(dto.VisitOrgName), x => x.VisitOrgName!.Contains(dto.VisitOrgName!))
+				.WhereIF(!string.IsNullOrEmpty(dto.OrgProcessingResults), x => SqlFunc.JsonField(x.OrgProcessingResults, "Key") == dto.OrgProcessingResults)
+				.WhereIF(!string.IsNullOrEmpty(dto.OrgHandledAttitude), x => SqlFunc.JsonListObjectAny(x.OrgHandledAttitude, "Key", dto.OrgHandledAttitude))
+				.WhereIF(!string.IsNullOrEmpty(dto.OrgNoSatisfiedReason), x => SqlFunc.JsonField(x.OrgNoSatisfiedReason, "Key") == dto.OrgNoSatisfiedReason)
+				.Where((x, s) => x.OrderVisit.VisitState != EVisitState.None && x.OrderVisit.IsCanHandle);
+			if (_sessionContext.OrgId != null && !_sessionContext.OrgIsCenter)
+			{
+				query.WhereIF(!string.IsNullOrEmpty(dto.Keyword),
+						(x, s) => x.OrderVisit.Order.Title.Contains(dto.Keyword!) ||
+								  x.OrderVisit.Order.No.Contains(dto.Keyword!))
+					.Where((x, s) => x.VisitTarget == EVisitTarget.Org && x.VisitOrgCode.StartsWith(_sessionContext.OrgId) && (
+						SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "1" ||
+						SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "2" ||
+						SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "1" ||
+						SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "2"
+					));
+			}
+			else
+			{
+				query.WhereIF(!string.IsNullOrEmpty(dto.Keyword),
+						(x, s) => x.OrderVisit.Order.Title.Contains(dto.Keyword!) ||
+								  x.OrderVisit.Order.No.Contains(dto.Keyword!))
+					.Where((x, s) => x.VisitTarget == EVisitTarget.Org && (
+						SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "1" ||
+						SqlFunc.JsonField(x.OrgProcessingResults, "Key") == "2" ||
+						SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "1" ||
+						SqlFunc.JsonField(x.OrgHandledAttitude, "Key") == "2"
+					));
+			}
+
+			return query.OrderByDescending((x, s) => x.CreationTime);
+		}
+
+		/// <summary>
+		/// 二次办理列表查询
+		/// </summary>
+		/// <returns></returns>
+		public ISugarQueryable<OrderSecondaryHandling> Query(SecondaryHandlingListDto dto, CancellationToken cancellationToken)
+		{
+			return _orderSecondaryHandlingRepository.Queryable()
+				.Includes(x => x.Order)
+				.Includes(x => x.VisitDetail)
+				.Includes(x => x.Visit, d => d.Order)
+				.Where(x=>x.State> ESecondaryHandlingState.NotApply)
+				.WhereIF(!string.IsNullOrEmpty(dto.Keyword),
+					x => x.Visit.Order.Title.Contains(dto.Keyword!) || x.Visit.Order.No.Contains(dto.Keyword!))
+				.WhereIF(dto.Status is ESecondaryHandlingState.Apply, x => x.State == ESecondaryHandlingState.Apply)
+				.WhereIF(dto.Status is ESecondaryHandlingState.Handled, x => x.State != ESecondaryHandlingState.Apply)
+				.WhereIF(dto.Status is ESecondaryHandlingState.End, x => x.State == ESecondaryHandlingState.End)
+				.WhereIF(dto.Status is ESecondaryHandlingState.Refuse, x => x.State == ESecondaryHandlingState.Refuse)
+				.WhereIF(dto.CreationTimeStart.HasValue, x => x.CreationTime >= dto.CreationTimeStart)
+				.WhereIF(dto.CreationTimeEnd.HasValue, x => x.CreationTime <= dto.CreationTimeEnd)
+				.WhereIF(!string.IsNullOrEmpty(dto.OrderId), x => x.OrderId == dto.OrderId)
+				.OrderByDescending(x => x.CreationTime);
+		}
+
+		/// <summary>
+		/// 获取实体
+		/// </summary>
+		/// <returns></returns>
+		public async Task<OrderSecondaryHandling> Entity(string id, CancellationToken cancellationToken)
+		{
+			return await _orderSecondaryHandlingRepository.Queryable()
+				.FirstAsync(x => x.Id == id, cancellationToken);
+		}
+
+	}
+}

+ 5 - 0
src/Hotline.Share/Dtos/FlowEngine/Workflow/WorkflowDto.cs

@@ -107,6 +107,11 @@ namespace Hotline.Share.Dtos.FlowEngine.Workflow
         /// </summary>
         public DateTime? ActualHandleTime { get; set; }
 
+        /// <summary>
+        /// 实际办理节点名称(会签状态此字段保存最外层会签发起节点名称)
+        /// </summary>
+        public string? ActualHandleStepName { get; set; }
+
 	}
 
     public class WorkflowAssignDto

+ 4 - 0
src/Hotline.Share/Dtos/Order/OrderScreenDto.cs

@@ -5,6 +5,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using Hotline.Share.Dtos.FlowEngine.Workflow;
 using XF.Utility.EnumExtensions;
 
 namespace Hotline.Share.Dtos.Order
@@ -114,6 +115,9 @@ namespace Hotline.Share.Dtos.Order
 		/// </summary>
 		public OrderDto Order { get; set; }
 
+
+		public WorkflowDto Workflow { get; set; }
+
 		/// <summary>
 		/// 回访明细id
 		/// </summary>

+ 185 - 0
src/Hotline.Share/Dtos/Order/OrderSecondaryHandlingDto.cs

@@ -0,0 +1,185 @@
+using Hotline.Share.Dtos.File;
+using Hotline.Share.Enums.Order;
+using Hotline.Share.Requests;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Share.Dtos.Order
+{
+	public class OrderSecondaryHandlingDto: OrderSecondaryHandlingBaseDto
+	{
+		/// <summary>
+		/// 工单ID
+		/// </summary>
+		public string OrderId { get; set; }
+
+		/// <summary>
+		/// 状态
+		/// </summary>
+		public ESecondaryHandlingState? State { get; set; }
+
+		/// <summary>
+		/// 申请理由
+		/// </summary>
+		public string? Content { get; set; }
+
+		/// <summary>
+		/// 审批意见
+		/// </summary>
+		public string? AuditContent { get; set; }
+
+		/// <summary>
+		/// 工单
+		/// </summary>
+		public OrderDto Order { get; set; }
+
+		/// <summary>
+		/// 回访
+		/// </summary>
+		public OrderVisitDetailDto VisitDetail { get; set; }
+
+		/// <summary>
+		/// 回访
+		/// </summary>
+		public OrderVisitDto Visit { get; set; }
+
+		/// <summary>
+		/// 审批人ID
+		/// </summary>
+		public string? AuditId { get; set; }
+
+		public string? AuditUser { get; set; }
+
+		/// <summary>
+		/// 审批时间
+		/// </summary>
+		public DateTime? AuditTime { get; set; }
+
+		/// <summary>
+		/// 申请部门ID
+		/// </summary>
+		public string ApplyOrgId { get; set; }
+
+		/// <summary>
+		/// 申请部门名称
+		/// </summary>
+		public string ApplyOrgName { get; set; }
+
+		/// <summary>
+		/// 附件列表
+		/// </summary>
+		public List<FileDto> Files { get; set; } = new();
+
+	}
+
+	public class AddOrderSecondaryHandlingDto {
+
+		public string Id { get; set; }
+
+		/// <summary>
+		/// 工单ID
+		/// </summary>
+		public string OrderId { get; set; }
+
+		/// <summary>
+		/// 回访id
+		/// </summary>
+		public string VisitId { get; set; }
+
+		/// <summary>
+		/// 回访明细id
+		/// </summary>
+		public string VisitDetailId { get; set; }
+
+		/// <summary>
+		/// 申请理由
+		/// </summary>
+		public string? Content { get; set; }
+
+		/// <summary>
+		/// 附件列表
+		/// </summary>
+		public List<FileDto> Files { get; set; } = new();
+
+		public List<FileJson>? FileJson { get; set; }
+	}
+
+	public class AuditOrderSecondaryHandlingDto
+	{
+		public string Id { get; set; }
+		/// <summary>
+		/// 状态
+		/// </summary>
+		public ESecondaryHandlingState? State { get; set; }
+
+
+		/// <summary>
+		/// 审批意见
+		/// </summary>
+		public string? AuditContent { get; set; }
+
+		public List<string> Ids { get; set; }
+	}
+
+	public class SendBackOrderSecondaryHandlingDto
+	{
+		public string Id { get; set; }
+
+		/// <summary>
+		/// 退回意见
+		/// </summary>
+		public string? SendBackContent { get; set; }
+	}
+
+	public class OrderSecondaryHandlingBaseDto
+	{
+		public DateTime? LastModificationTime { get; set; }
+
+		public bool IsDeleted { get; set; }
+
+		/// <summary>
+		/// 删除时间
+		/// </summary>
+		public DateTime? DeletionTime { get; set; }
+
+
+		/// <summary>
+		/// 创建时间
+		/// </summary>
+		public DateTime CreationTime { get; set; }
+
+		public string Id { get; set; }
+
+		/// <summary>
+		/// 组织Id
+		/// </summary>
+		public string? CreatorOrgId { get; set; }
+
+
+		public string? CreatorOrgName { get; set; }
+
+		/// <summary>
+		/// 创建人
+		/// </summary>
+		public string? CreatorId { get; set; }
+
+		public string? CreatorName { get; set; }
+	}
+
+	public record SecondaryHandlingListDto : PagedKeywordRequest
+	{
+		/// <summary>
+		/// 申请状态
+		/// </summary>
+		public ESecondaryHandlingState? Status { get; set; }
+
+		public DateTime? CreationTimeStart { get; set; }
+		public DateTime? CreationTimeEnd { get; set; }
+
+		public string? OrderId { get; set; }
+
+	}
+}

+ 2 - 0
src/Hotline.Share/Dtos/Order/OrderVisitDto.cs

@@ -372,6 +372,8 @@ namespace Hotline.Share.Dtos.Order
 
         public OrderVisitDto OrderVisit { get; set; }
 
+        public OrderSecondaryHandlingDto SecondaryHandling { get; set; }
+
         public OrderDto Order => OrderVisit != null ? OrderVisit.Order : null;
 
         /// <summary>

+ 6 - 0
src/Hotline.Share/Enums/FlowEngine/EWorkflowStepStatus.cs

@@ -24,4 +24,10 @@ public enum EWorkflowStepStatus
     /// </summary>
     [Description("已办理")]
     Handled = 2,
+
+    ///// <summary>
+    ///// 未办理,由结束会签结束掉
+    ///// </summary>
+    //[Description("已办理")]
+    //Terminal = 3,
 }

+ 43 - 0
src/Hotline.Share/Enums/Order/ESecondaryHandlingState.cs

@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Share.Enums.Order
+{
+	public enum ESecondaryHandlingState
+	{
+
+		/// <summary>
+		/// 待申请
+		/// </summary>
+		[Description("待申请")]
+		NotApply = 0,
+
+		/// <summary>
+		/// 待办
+		/// </summary>
+		[Description("待办")]
+		Apply = 1,
+
+		/// <summary>
+		/// 审批通过
+		/// </summary>
+		[Description("审批通过")]
+		End = 2,
+
+		/// <summary>
+		/// 审批拒绝
+		/// </summary>
+		[Description("审批拒绝")]
+		Refuse = 3,
+
+		/// <summary>
+		/// 已办理
+		/// </summary>
+		[Description("已办理")]
+		Handled = 4,
+	}
+}

+ 18 - 1
src/Hotline/FlowEngine/Workflows/StepBasicEntity.cs

@@ -363,17 +363,20 @@ public abstract class StepBasicEntity : CreationEntity
         AcceptorOrgAreaCode = orgAreaCode;
         AcceptorOrgAreaName = orgAreaName;
         AcceptTime = DateTime.Now;
+        Status = EWorkflowStepStatus.WaitForHandle;
     }
 
     public void Handle(
         string userId, string? userName,
         string orgId, string? orgName,
         string? orgAreaCode, string? orgAreaName,
-        bool orgIsCenter, string opinion)
+        bool orgIsCenter, string opinion,
+        string? nextStepCode = null)
     {
         if (!HasAccepted())
             Accept(userId, userName, orgId, orgName, orgAreaCode, orgAreaName);
 
+        Status = EWorkflowStepStatus.Handled;
         HandlerId = userId;
         HandlerName = userName;
         HandlerOrgId = orgId;
@@ -389,7 +392,21 @@ public abstract class StepBasicEntity : CreationEntity
         ExpiredStatus = HandleTime > StepExpiredTime
             ? EExpiredStatus.Expired
             : EExpiredStatus.Normal;
+
+        if (!IsInCountersign()
+            && InstanceMode is EInstanceMode.Config
+            && StepType is not EStepType.End)
+        {
+            var step = NextSteps.FirstOrDefault(d => d.Code == nextStepCode);
+            if (step != null)
+                step.Selected = true;
+        }
     }
 
+    /// <summary>
+    /// 是否处于会签流程中(不包含顶层发起会签节点)
+    /// </summary>
+    public bool IsInCountersign() => CountersignPosition != ECountersignPosition.None;
+
     #endregion
 }

+ 1 - 3
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -1723,7 +1723,6 @@ namespace Hotline.FlowEngine.Workflows
             return countersign;
         }
 
-
         private async Task JumpTraceAsync(string workflowId, RecallDto dto, CancellationToken cancellationToken)
         {
             //未办理的traces
@@ -1766,8 +1765,7 @@ namespace Hotline.FlowEngine.Workflows
         }
 
         private async Task<WorkflowTrace> PreviousTraceAsync(string workflowId, PreviousWorkflowDto dto,
-            WorkflowStep step,
-            CancellationToken cancellationToken)
+            WorkflowStep step, CancellationToken cancellationToken)
         {
             var trace = await GetWorkflowTraceAsync(workflowId, step.Id, cancellationToken);
             _mapper.Map(dto, trace);

+ 35 - 36
src/Hotline/FlowEngine/Workflows/WorkflowStep.cs

@@ -32,43 +32,42 @@ public class WorkflowStep : StepBasicEntity
     ///// </summary>
     //public bool HasStartedCountersign() => !string.IsNullOrEmpty(StartCountersignId);
 
-    /// <summary>
-    /// 接办
-    /// </summary>
-    public void Accept(string userId, string? userName, string orgId, string? orgName, string? orgAreaCode,
-        string? orgAreaName)
-    {
-        AcceptorId = userId;
-        AcceptorName = userName;
-        AcceptorOrgId = orgId;
-        AcceptorOrgName = orgName;
-        AcceptorOrgAreaCode = orgAreaCode;
-        AcceptorOrgAreaName = orgAreaName;
-        AcceptTime = DateTime.Now;
-        Status = EWorkflowStepStatus.WaitForHandle;
-    }
+    ///// <summary>
+    ///// 接办
+    ///// </summary>
+    //public void Accept(string userId, string? userName, string orgId, string? orgName, string? orgAreaCode,
+    //    string? orgAreaName)
+    //{
+    //    AcceptorId = userId;
+    //    AcceptorName = userName;
+    //    AcceptorOrgId = orgId;
+    //    AcceptorOrgName = orgName;
+    //    AcceptorOrgAreaCode = orgAreaCode;
+    //    AcceptorOrgAreaName = orgAreaName;
+    //    AcceptTime = DateTime.Now;
+    //    Status = EWorkflowStepStatus.WaitForHandle;
+    //}
 
-    /// <summary>
-    /// 节点办理完成
-    /// </summary>
-    public void Handle(
-        string userId, string? userName,
-        string orgId, string? orgName,
-        string? orgAreaCode, string? orgAreaName,
-        bool orgIsCenter, string opinion, string nextStepCode)
-    {
-        base.Handle(userId, userName, orgId, orgName, orgAreaCode, orgAreaName, orgIsCenter, opinion);
-        Status = EWorkflowStepStatus.Handled;
-
-        if (!IsInCountersign()
-            && InstanceMode is EInstanceMode.Config
-            && StepType is not EStepType.End)
-        {
-            var step = NextSteps.FirstOrDefault(d => d.Code == nextStepCode);
-            if (step != null)
-                step.Selected = true;
-        }
-    }
+    ///// <summary>
+    ///// 节点办理完成
+    ///// </summary>
+    //public void Handle(
+    //    string userId, string? userName,
+    //    string orgId, string? orgName,
+    //    string? orgAreaCode, string? orgAreaName,
+    //    bool orgIsCenter, string opinion, string nextStepCode)
+    //{
+    //    base.Handle(userId, userName, orgId, orgName, orgAreaCode, orgAreaName, orgIsCenter, opinion);
+        
+    //    if (!IsInCountersign()
+    //        && InstanceMode is EInstanceMode.Config
+    //        && StepType is not EStepType.End)
+    //    {
+    //        var step = NextSteps.FirstOrDefault(d => d.Code == nextStepCode);
+    //        if (step != null)
+    //            step.Selected = true;
+    //    }
+    //}
 
     /// <summary>
     /// 会签结束

+ 113 - 0
src/Hotline/Orders/OrderSecondaryHandling.cs

@@ -0,0 +1,113 @@
+using Hotline.Share.Dtos.File;
+using Hotline.Share.Enums.Order;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Repository;
+
+namespace Hotline.Orders
+{
+	[Description("二次办理")]
+	public class OrderSecondaryHandling : FullStateEntity
+	{
+		/// <summary>
+		/// 工单ID
+		/// </summary>
+		[SugarColumn(ColumnDescription = "工单ID")]
+		public string OrderId { get; set; }
+
+
+		/// <summary>
+		/// 回访id
+		/// </summary>
+		[SugarColumn(ColumnDescription = "回访id")]
+		public string VisitId { get; set; }
+
+		/// <summary>
+		/// 回访明细id
+		/// </summary>
+		[SugarColumn(ColumnDescription = "回访明细id")]
+		public string VisitDetailId { get; set; }
+
+		/// <summary>
+		/// 状态
+		/// </summary>
+		[SugarColumn(ColumnDescription = "状态")]
+		public ESecondaryHandlingState? State { get; set; }
+
+		/// <summary>
+		/// 申请理由
+		/// </summary>
+		[SugarColumn(ColumnDescription = "申请理由", ColumnDataType = "varchar(2000)")]
+		public string? Content { get; set; }
+
+		/// <summary>
+		/// 退回意见
+		/// </summary>
+		[SugarColumn(ColumnDescription = "退回意见", ColumnDataType = "varchar(2000)")]
+		public string? SendBackContent { get; set; }
+
+		/// <summary>
+		/// 审批意见
+		/// </summary>
+		[SugarColumn(ColumnDescription = "审批意见", ColumnDataType = "varchar(2000)")]
+		public string? AuditContent { get; set; }
+
+		/// <summary>
+		/// 工单
+		/// </summary>
+		[Navigate(NavigateType.OneToOne, nameof(OrderId))]
+		public Order Order { get; set; }
+
+
+		/// <summary>
+		/// 回访
+		/// </summary>
+		[Navigate(NavigateType.OneToOne, nameof(VisitDetailId))]
+		public OrderVisitDetail VisitDetail { get; set; }
+
+		/// <summary>
+		/// 回访
+		/// </summary>
+		[Navigate(NavigateType.OneToOne, nameof(VisitId))]
+		public OrderVisit Visit { get; set; }
+
+		/// <summary>
+		/// 审批人ID
+		/// </summary>
+		[SugarColumn(ColumnDescription = "审批人ID")]
+		public string? AuditId { get; set; }
+
+		[SugarColumn(ColumnDescription = "审批人")]
+		public string? AuditUser { get; set; }
+
+		/// <summary>
+		/// 审批时间
+		/// </summary>
+		public DateTime? AuditTime { get; set; }
+
+		/// <summary>
+		/// 申请部门ID
+		/// </summary>
+		[SugarColumn(ColumnDescription = "申请部门ID")]
+		public string ApplyOrgId { get; set; }
+
+		/// <summary>
+		/// 申请部门名称
+		/// </summary>
+		[SugarColumn(ColumnDescription = "申请部门名称")]
+		public string ApplyOrgName { get; set; }
+
+		[SugarColumn(ColumnDataType = "json", IsJson = true, IsNullable = true)]
+		public List<FileJson>? FileJson { get; set; }
+
+		/// <summary>
+		/// 回访状态
+		/// </summary>
+		public EVisitState VisitState { get; set; }
+	}
+}

+ 8 - 2
src/Hotline/Orders/OrderVisitDetail.cs

@@ -1,5 +1,6 @@
 using Hotline.Settings.Hotspots;
 using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.Order;
 using Hotline.Share.Enums.Order;
 using SqlSugar;
 using XF.Domain.Repository;
@@ -19,9 +20,14 @@ namespace Hotline.Orders
         public OrderVisit OrderVisit { get; set; }
 
         /// <summary>
-        /// 语音评价(话务评价)
+        /// 通话记录
         /// </summary>
-        public EVoiceEvaluate? VoiceEvaluate { get; set; }
+        [Navigate(NavigateType.OneToOne, nameof(Id),nameof(OrderSecondaryHandling.VisitDetailId))]
+        public OrderSecondaryHandling SecondaryHandling { get; set; }
+		/// <summary>
+		/// 语音评价(话务评价)
+		/// </summary>
+		public EVoiceEvaluate? VoiceEvaluate { get; set; }
 
         /// <summary>
         /// 话务员评价(话务评价)