浏览代码

Merge branch 'release' into feature/refactor_workflow

xf 6 月之前
父节点
当前提交
bc9e09e5ac

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

@@ -30,6 +30,7 @@ using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
 using SqlSugar;
 using System.Data;
+using Hotline.SeedData;
 using XF.Domain.Authentications;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
@@ -2518,7 +2519,8 @@ namespace Hotline.Api.Controllers.Bi
                        .LeftJoin<Workflow>((x, w) => x.WorkflowId == w.Id)
                        //.LeftJoin<WorkflowStepHandler>((x, w, wfsh) => x.StepId == wfsh.WorkflowStepId && wfsh.IsActualHandler == true)
                        .InnerJoin<SchedulingUser>((x, w, su) => x.HandlerId == su.UserId)
-                       .Where((x, w, su) => w.ModuleCode == "OrderHandle" && x.BusinessType == EBusinessType.Send)
+                       .Where((x, w, su) => w.ModuleCode == "OrderHandle" && x.BusinessType == EBusinessType.Send && x.Status == EWorkflowStepStatus.Handled
+	                && !string.IsNullOrEmpty(x.NextMainHandler) && x.NextMainHandler != OrgSeedData.CenterId)
                        .Where((x, w, su) => x.CreationTime >= dto.StartTime.Value)
                        .Where((x, w, su) => x.CreationTime <= dto.EndTime.Value)
                        .GroupBy((x, w, su) => x.WorkflowId)

+ 1 - 2
src/Hotline.Api/Controllers/DataSharingController.cs

@@ -179,8 +179,7 @@ namespace Hotline.Api.Controllers
         public async Task<PagedDto<PublishDto>> GetOrderByListOpen([FromBody] GetOrderList dto)
         {
             var (total, items) = await _orderRepository.Queryable()
-                .Includes(d => d.OrderPublish)
-                .Where(p => p.OrderPublish.PublishState == true)
+                .Where(p => p.IsPublicity == true)
                 .WhereIF(!string.IsNullOrEmpty(dto.No), p => p.No == dto.No)
                 .WhereIF(!string.IsNullOrEmpty(dto.Title), p => p.Title.Contains(dto.Title))
                 .WhereIF(!string.IsNullOrEmpty(dto.Mobile), p => p.Contact.Contains(dto.Mobile))

+ 23 - 7
src/Hotline.Api/Controllers/OrderController.cs

@@ -6132,12 +6132,20 @@ public class OrderController : BaseController
                     }
 
                     var SourceCode = (ESource)Enum.Parse(typeof(ESource), allowSource);
+                    var acceptType = _sysDicDataCacheManager.AcceptType
+                        .FirstOrDefault(m => m.DicDataName == item.AcceptType);
+
+                    if (acceptType == null)
+                    {
+                        errorMessage.Append($"第{i + 1}行: 不能通过受理类型 {item.AcceptType} 查询到对应的受理类型Code\r\n");
+                        continue;
+                    }
 
                     var order = await _orderRepository.GetAsync(x => x.ExternalId == item.ExternalId && x.Source == SourceCode,
                         HttpContext.RequestAborted) ?? new Orders.Order();
                     item.Source = SourceCode.ToString();
                     order = _mapper.Map(item, order);
-
+                    order.AcceptTypeCode = acceptType.DicDataValue;
                     order.SourceChannel = SourceCode.GetDescription();
                     order.SourceChannelCode = ((int)SourceCode).ToString();
 
@@ -6871,12 +6879,20 @@ public class OrderController : BaseController
                 new(dto.Handler.UserId,dto.Handler.Username,dto.Handler.OrgId,dto.Handler.OrgName,step.RoleId,step.RoleName, new List<WorkflowStep>{step})
             }, HttpContext.RequestAborted);
             var status = EOrderStatus.HandOver;
-            if (step.BusinessType == EBusinessType.Seat && step.StepType == EStepType.Start)
-                status = EOrderStatus.HandOverToUnAccept;
-            await _orderRepository.Updateable()
-                .SetColumns(o => new Orders.Order() { Status = status })
-                .Where(o => o.Id == dto.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
-        }
+			if (step.BusinessType == EBusinessType.Seat && step.StepType == EStepType.Start)
+			{
+				status = EOrderStatus.HandOverToUnAccept;
+				await _orderRepository.Updateable()
+					.SetColumns(o => new Orders.Order() { Status = status, SignerId = dto.Handler.UserId })
+					.Where(o => o.Id == dto.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
+			}
+			else
+			{
+				await _orderRepository.Updateable()
+					.SetColumns(o => new Orders.Order() { Status = status })
+					.Where(o => o.Id == dto.OrderId).ExecuteCommandAsync(HttpContext.RequestAborted);
+			}
+		}
     }
 
     #endregion

+ 16 - 0
src/Hotline.Api/Controllers/TestController.cs

@@ -41,6 +41,7 @@ using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.JudicialManagement;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Quality;
+using Hotline.Share.Mq;
 using Hotline.Users;
 using MapsterMapper;
 using MediatR;
@@ -977,4 +978,19 @@ ICallApplication callApplication,
 
         _logger.LogWarning($"推送完成");
     }
+
+
+    /// <summary>
+    /// 自动延期测试
+    /// </summary>
+    /// <param name="ExpiredTime"></param>
+    /// <param name="orderId"></param>
+    /// <returns></returns>
+    [HttpGet("automatic_delay")]
+    [AllowAnonymous]
+    public async Task AutomaticDelay(DateTime ExpiredTime, string orderId) {
+
+	    _capPublisher.PublishDelay(ExpiredTime - DateTime.Now.AddHours(1), EventNames.HotlineOrderAutomaticDelay, new PublishAutomaticDelayDto() { OrderId = orderId });
+	}
+
 }

+ 1 - 1
src/Hotline.Api/Controllers/WebPortalController.cs

@@ -655,7 +655,7 @@ namespace Hotline.Api.Controllers
         [HttpPost("getorderid")]
         public async Task<OpenResponse> GetOrderId([FromBody] GetOrderCodePwd dto)
         {
-            var data = await _orderRepository.GetAsync(p => p.No == dto.OrderNo && p.Password == dto.Pwd && p.Status > EOrderStatus.Published, HttpContext.RequestAborted);
+            var data = await _orderRepository.GetAsync(p => p.No == dto.OrderNo && p.Password == dto.Pwd, HttpContext.RequestAborted);//&& p.Status > EOrderStatus.Published
             return OpenResponse.Ok(WebPortalDeResponse<string>.Success(data?.Id));
         }
 

+ 32 - 45
src/Hotline.Application/Handlers/FlowEngine/WorkflowNextHandler.cs

@@ -53,7 +53,7 @@ public class WorkflowNextHandler : INotificationHandler<NextStepNotify>
     private readonly ISystemSettingCacheManager _systemSettingCacheManager;
     private readonly Publisher _publisher;
 
-	public WorkflowNextHandler(
+    public WorkflowNextHandler(
         IOrderDomainService orderDomainService,
         IOrderRepository orderRepository,
         ICapPublisher capPublisher,
@@ -118,54 +118,35 @@ public class WorkflowNextHandler : INotificationHandler<NextStepNotify>
 
                     if (_appOptions.Value.IsZiGong && data.FlowDirection is EFlowDirection.CenterToOrg)
                     {
-                        var expiredTimeConfig = await _expireTime.CalcExpiredTime(DateTime.Now, EFlowDirection.CenterToOrg , order.Adapt<OrderTimeClacInfo>());
+                        var expiredTimeConfig =
+                            await _expireTime.CalcExpiredTime(DateTime.Now, EFlowDirection.CenterToOrg, order.Adapt<OrderTimeClacInfo>());
                         order.CenterToOrg(expiredTimeConfig.TimeText, expiredTimeConfig.Count,
                             expiredTimeConfig.TimeType, expiredTimeConfig.ExpiredTime, expiredTimeConfig.NearlyExpiredTime
-                            , expiredTimeConfig.NearlyExpiredTimeOne, notification.Dto.Opinion,notification.Trace.HandlerId, notification.Trace.HandlerName,true);
+                            , expiredTimeConfig.NearlyExpiredTimeOne, notification.Dto.Opinion, notification.Trace.HandlerId,
+                            notification.Trace.HandlerName, true);
                     }
 
-                    //var expiredTimeChanged = false;
-                    //if (data.FlowDirection.HasValue
-                    //    && data.External.TimeLimit.HasValue                   
-                    //    && data.External.TimeLimitUnit.HasValue)
-                    //{
-                    //    // 1. calc expiredTime 2. update order.expiredTime 3. update workflow.expiredTime 4. publish province
-
-                    //    // var expiredTime = _timeLimitDomainService.CalcEndTime(DateTime.Now,
-                    //    //     data.External.TimeLimitUnit.Value,
-                    //    //     data.External.TimeLimit.Value, data.FlowDirection is EFlowDirection.OrgToCenter);
-
-                    //    var expiredTimeConfig = _timeLimitDomainService.CalcEndTime(DateTime.Now,
-                    //        new TimeConfig(data.External.TimeLimit.Value, data.External.TimeLimitUnit.Value), order.AcceptTypeCode);
-
-                    //    if (data.FlowDirection is EFlowDirection.OrgToCenter)
-                    //    {
-                    //        order.OrgToCenter(expiredTimeConfig.TimeText, expiredTimeConfig.Count,
-                    //            expiredTimeConfig.TimeType, expiredTimeConfig.ExpiredTime, expiredTimeConfig.NearlyExpiredTime);
-                    //    }
-                    //    else if (data.FlowDirection is EFlowDirection.CenterToOrg)
-                    //    {
-                    //        order.CenterToOrg(expiredTimeConfig.TimeText, expiredTimeConfig.Count,
-                    //            expiredTimeConfig.TimeType, expiredTimeConfig.ExpiredTime, expiredTimeConfig.NearlyExpiredTime);
-                    //        //写入质检
-                    //        await _qualityApplication.AddQualityAsync(EQualitySource.Send, order.Id, cancellationToken);
-                    //    }
-
-                    //    await _workflowDomainService.UpdateExpiredTimeAsync(workflow,
-                    //        expiredTimeConfig.ExpiredTime, expiredTimeConfig.TimeText,
-                    //        expiredTimeConfig.Count, expiredTimeConfig.TimeType, expiredTimeConfig.NearlyExpiredTime, cancellationToken);
+                    if (order.CounterSignType is ECounterSignType.Center &&
+                        notification.Trace.BusinessType is EBusinessType.Seat or EBusinessType.Send &&
+                        notification.Workflow.IsTopCountersignEndStep(notification.Trace) &&
+                        data.FlowDirection is EFlowDirection.CenterToOrg)
+                    {
+                        bool.TryParse(
+                            _systemSettingCacheManager.GetSetting(SettingConstants.IsResetCenterCountersignType)?.SettingValue[0],
+                            out bool isResetCenterCountersignType);
+                        if (isResetCenterCountersignType)
+                            order.CounterSignType = null;
+                    }
 
-                    //    expiredTimeChanged = true;
-                    //}
                     if (data.FlowDirection is EFlowDirection.CenterToOrg)
                         order.SendBackAuditEndTime = await _expireTime.GetWorkDay(DateTime.Now);
-					await _orderRepository.Updateable(order).ExecuteCommandAsync(cancellationToken);
-                    //await _orderRepository.UpdateAsync(order, cancellationToken);
+                    await _orderRepository.UpdateAsync(order, cancellationToken);
 
                     //司法行政监督管理-推诿工单
                     //如果没开启则不处理
                     var isOpenJudicialManagement = _systemSettingCacheManager.GetSetting(SettingConstants.IsOpenJudicialManagement)?.SettingValue[0];
-                    if (isOpenJudicialManagement == "true" && notification.Trace.StepType != EStepType.Summary && notification.Trace.StepType != EStepType.End && !notification.Trace.IsCountersignEndStep)
+                    if (isOpenJudicialManagement == "true" && notification.Trace.StepType != EStepType.Summary &&
+                        notification.Trace.StepType != EStepType.End && !notification.Trace.IsCountersignEndStep)
                         await _publisher.PublishAsync(new AddPassTheBuckOrderNotify(order, _sessionContext.RequiredOrgId, _sessionContext.OrgName),
                             PublishStrategy.ParallelWhenAll, cancellationToken);
 
@@ -176,7 +157,8 @@ public class WorkflowNextHandler : INotificationHandler<NextStepNotify>
                             switch (notification.FlowAssignInfo.FlowAssignType)
                             {
                                 case EFlowAssignType.Org:
-                                    var orgCodes = notification.Trace.NextHandlers.Select(x => x.OrgId); //notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
+                                    var orgCodes = notification.Trace.NextHandlers.Select(x =>
+                                        x.OrgId); //notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
                                     var acceptSmsRoleIds = _systemSettingCacheManager.GetSetting(SettingConstants.AcceptSmsRoleIds)?.SettingValue;
                                     var orgList = await _userRepository.Queryable()
                                         .Where(x => orgCodes.Contains(x.OrgId) && x.Roles.Any(d => acceptSmsRoleIds.Contains(d.Id)))
@@ -196,14 +178,16 @@ public class WorkflowNextHandler : INotificationHandler<NextStepNotify>
                                                 TemplateCode = "1007",
                                                 Params = new List<string>() { order.No },
                                                 TelNumber = item.PhoneNo,
-
                                             };
                                             await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
                                         }
                                     }
+
                                     break;
                                 case EFlowAssignType.User:
-                                    var userCodes = notification.Trace.NextHandlers.Select(x => x.UserId); //notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
+                                    var userCodes =
+                                        notification.Trace.NextHandlers.Select(x =>
+                                            x.UserId); //notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
                                     var userList = await _userRepository.Queryable()
                                         .Where(x => userCodes.Contains(x.Id) && !string.IsNullOrEmpty(x.PhoneNo))
                                         .ToListAsync(cancellationToken);
@@ -220,17 +204,20 @@ public class WorkflowNextHandler : INotificationHandler<NextStepNotify>
                                             TemplateCode = "1007",
                                             Params = new List<string>() { order.No },
                                             TelNumber = item.PhoneNo,
-
                                         };
                                         await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
                                     }
+
                                     break;
                                 default:
                                     break;
                             }
                         }
                     }
-                    catch { }
+                    catch
+                    {
+                    }
+
                     var orderDto = _mapper.Map<OrderDto>(order);
                     await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFlowHandled, new OrderFlowDto
                     {
@@ -337,7 +324,8 @@ public class WorkflowNextHandler : INotificationHandler<NextStepNotify>
                                         await _orderDelayRepository.UpdateAsync(orderDelay);
                                         //推送
                                         var publishOrderDelay = _mapper.Map<PublishOrderDelayDto>(orderDelay);
-                                        await _capPublisher.PublishAsync(EventNames.HotlineOrderApplyDelay, publishOrderDelay, cancellationToken: cancellationToken);
+                                        await _capPublisher.PublishAsync(EventNames.HotlineOrderApplyDelay, publishOrderDelay,
+                                            cancellationToken: cancellationToken);
 
                                         //await _provinceService.DelayCaseInfoSend(publishOrderDelay, cancellationToken);
                                     }
@@ -354,7 +342,6 @@ public class WorkflowNextHandler : INotificationHandler<NextStepNotify>
 
                     break;
             }
-
         }
         catch (Exception e)
         {

+ 27 - 5
src/Hotline.Application/Orders/OrderApplication.cs

@@ -2222,25 +2222,47 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     /// <returns></returns>
     public async Task<List<SendOrderReportOutDto>> SendOrderReportAsync(QuerySendOrderRequest dto)
     {
-        var items = await _workflowTraceRepository.Queryable()
+        var itemsHandled =  _workflowTraceRepository.Queryable()
             .LeftJoin<Workflow>((x, w) => x.WorkflowId == w.Id)
-            //.LeftJoin<WorkflowStepHandler>((x, w, wsh) => x.StepId == wsh.WorkflowStepId && wsh.IsActualHandler == true)
             .InnerJoin<SchedulingUser>((x, w, su) => x.HandlerId == su.UserId)
             .Where((x, w, su) => w.ModuleCode == "OrderHandle" && x.BusinessType == EBusinessType.Send && x.Status == EWorkflowStepStatus.Handled)
             .Where((x, w, su) => x.CreationTime >= dto.StartTime.Value)
             .Where((x, w, su) => x.CreationTime <= dto.EndTime.Value)
             .WhereIF(!string.IsNullOrEmpty(dto.UserName), (x, w, su) => su.UserName == dto.UserName)
             .GroupBy((x, w, su) => new { su.UserId, su.UserName })
-            //.Having((x, w, wsh, su) => SqlFunc.AggregateCount(x.WorkflowId) == 1)
             .Select((x, w, su) => new BiOrderSendVo
             {
                 UserId = su.UserId,
                 UserName = su.UserName,
                 SendOrderNum = SqlFunc.AggregateDistinctCount(w.ExternalId),
-                NoSendOrderNum = SqlFunc.AggregateSum(SqlFunc.IIF(x.HandlerId == null || x.HandlerId == "", 1, 0)),
+                NoSendOrderNum =  0,
+            });
+        var itemsNo = _workflowTraceRepository.Queryable()
+	        .LeftJoin<Workflow>((x, w) => x.WorkflowId == w.Id)
+	        .InnerJoin<SchedulingUser>((x, w, su) => x.HandlerId == su.UserId)
+	        .Where((x, w, su) => w.ModuleCode == "OrderHandle" && x.BusinessType == EBusinessType.Send && x.Status != EWorkflowStepStatus.Handled)
+	        .Where((x, w, su) => x.CreationTime >= dto.StartTime.Value)
+	        .Where((x, w, su) => x.CreationTime <= dto.EndTime.Value)
+	        .WhereIF(!string.IsNullOrEmpty(dto.UserName), (x, w, su) => su.UserName == dto.UserName)
+	        .GroupBy((x, w, su) => new { su.UserId, su.UserName })
+	        .Select((x, w, su) => new BiOrderSendVo
+	        {
+		        UserId = su.UserId,
+		        UserName = su.UserName,
+		        SendOrderNum = 0,
+		        NoSendOrderNum = SqlFunc.AggregateDistinctCount(w.ExternalId),
+	        });
+        var items = await itemsHandled.LeftJoin(itemsNo, (hand, nohand) => hand.UserId == nohand.UserId)
+            .GroupBy((hand, nohand) => new { hand.UserId , hand.UserName } )
+            .Select((hand, nohand) => new BiOrderSendVo
+            {
+                UserId = hand.UserId,
+                UserName = hand.UserName,
+                SendOrderNum = SqlFunc.AggregateSum(hand.SendOrderNum),
+                NoSendOrderNum = SqlFunc.AggregateSum(nohand.NoSendOrderNum),
             }).ToListAsync();
 
-        var items2 = await _workflowTraceRepository.Queryable()
+		var items2 = await _workflowTraceRepository.Queryable()
             .LeftJoin<Workflow>((x, w) => x.WorkflowId == w.Id)
             //.LeftJoin<WorkflowStepHandler>((x, w, wfsh) => x.StepId == wfsh.WorkflowStepId && wfsh.IsActualHandler == true)
             .InnerJoin<SchedulingUser>((x, w, su) => x.HandlerId == su.UserId)

+ 6 - 5
src/Hotline.Application/Subscribers/InternalCapSubscriber.cs

@@ -235,11 +235,11 @@ namespace Hotline.Application.Subscribers
         public async Task AutomaticDelay(PublishAutomaticDelayDto dto, CancellationToken cancellationToken) 
         {
             var order = await _orderRepository.GetAsync(dto.OrderId, cancellationToken);
-            var expiredTime = DateTime.Now.AddHours(-1);
-            if (order != null && order.Status < EOrderStatus.Filed && order.ExpiredTime <= DateTime.Now)
-            {
-                if (order.ExpiredTime >= expiredTime)
-                {
+			var expiredTime = DateTime.Now.AddHours(1);
+			if (order != null && order.Status < EOrderStatus.Filed && order.ExpiredTime >= DateTime.Now)
+			{
+				if (order.ExpiredTime <= expiredTime)
+				{
                     var delayAny= await _orderDelayRepository.Queryable().Where(x => x.OrderId == order.Id && x.DelayState == EDelayState.Examining).AnyAsync();
                     if (!delayAny)
                     {
@@ -253,6 +253,7 @@ namespace Hotline.Application.Subscribers
 						}
 						else
 						{
+                            delay.OrderId = order.Id;
 							delay.EmployeeId = "";
 							delay.EmployeeName = "系统自动延期";
 							delay.ApplyOrgName = OrgSeedData.CenterName;

+ 1 - 0
src/Hotline/Caching/Interfaces/ISysDicDataCacheManager.cs

@@ -12,5 +12,6 @@ namespace Hotline.Caching.Interfaces
         IReadOnlyList<SystemDicData> GetSysDicDataCache(string code);
         IReadOnlyList<SystemDicData> GetVisitSatisfaction();
         void RemoveSysDicDataCache(string code);
+        IReadOnlyList<SystemDicData> AcceptType { get; }
     }
 }

+ 3 - 0
src/Hotline/Caching/Services/SysDicDataCacheManager.cs

@@ -17,6 +17,7 @@ namespace Hotline.Caching.Services
             _cacheSysDicData = cacheSysDicData;
         }
 
+
         public IReadOnlyList<SystemDicData> GetSysDicDataCache(string code)
         {
             var sysDicDataList = _cacheSysDicData.GetOrSet(code, k =>
@@ -29,6 +30,8 @@ namespace Hotline.Caching.Services
         public IReadOnlyList<SystemDicData> GetVisitSatisfaction()
             => GetSysDicDataCache(SysDicTypeConsts.VisitSatisfaction);
 
+        public IReadOnlyList<SystemDicData> AcceptType => GetSysDicDataCache(SysDicTypeConsts.AcceptType);
+
         public void RemoveSysDicDataCache(string code)
         {
             _cacheSysDicData.Remove(code);

+ 1 - 1
src/Hotline/FlowEngine/Workflows/Workflow.cs

@@ -886,7 +886,7 @@ public partial class Workflow
             CsActualHandleOrgIds.Add(orgId);
     }
 
-    public bool IsTopCountersignEndStep(WorkflowStep step)
+    public bool IsTopCountersignEndStep(StepBasicEntity step)
     {
         if (string.IsNullOrEmpty(TopCountersignStepId))
             throw new UserFriendlyException("该流程当前未开启会签");

+ 5 - 2
src/Hotline/Settings/SettingConstants.cs

@@ -524,8 +524,6 @@ namespace Hotline.Settings
 
 		#endregion
 
-        
-
         /// <summary>
         /// 定量查询返回数据条数上限
         /// </summary>
@@ -535,5 +533,10 @@ namespace Hotline.Settings
         /// 旧数据通知公告知识库附件地址	
         /// </summary>
         public const string OldFilesUrls = "OldFilesUrls";
+        
+        /// <summary>
+        /// 是否重置中心会签类型
+        /// </summary>
+        public const string IsResetCenterCountersignType = "IsResetCenterCountersignType";
     }
 }