Procházet zdrojové kódy

Merge branch 'release' of http://110.188.24.182:10023/Fengwo/hotline into release

田爽 před 6 měsíci
rodič
revize
f1691b5113

+ 17 - 11
src/Hotline.Api/Controllers/OrderRevocationController.cs

@@ -44,8 +44,8 @@ namespace Hotline.Api.Controllers
             ISystemSettingCacheManager systemSettingCacheManager,
             IRepository<SystemOrganize> systemOrganizeRepository,
             IRepository<User> userRepository,
-             IMediator mediator,
-             IWorkflowDomainService workflowDomainService)
+            IMediator mediator,
+            IWorkflowDomainService workflowDomainService)
         {
             _mapper = mapper;
             _orderRevocationRepository = orderRevocationRepository;
@@ -102,11 +102,16 @@ namespace Hotline.Api.Controllers
                         if (!string.IsNullOrEmpty(id))
                         {
                             #region 处理短信业务
+
                             //如果需要发短信、处理短信业务
                             if (dto.IsSendSms && !string.IsNullOrEmpty(order.WorkflowId))
-                            {  //查询当前工单的实际办理节点,如果在热线中心不处理,如果在部门需要更新期满时间
-                                var workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withSteps: true, withTraces: true, cancellationToken: HttpContext.RequestAborted);
-                                var nowWorkflow = workflow.Steps.Where(p => p.Id == order.ActualHandleStepId && p.BusinessType >= EBusinessType.Department && p.BusinessType <= EBusinessType.DepartmentLeader).FirstOrDefault();
+                            {
+                                //查询当前工单的实际办理节点,如果在热线中心不处理,如果在部门需要更新期满时间
+                                var workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withSteps: true, withTraces: true,
+                                    cancellationToken: HttpContext.RequestAborted);
+                                var nowWorkflow = workflow.Steps.Where(p =>
+                                    p.Id == order.ActualHandleStepId && p.BusinessType >= EBusinessType.Department &&
+                                    p.BusinessType <= EBusinessType.DepartmentLeader).FirstOrDefault();
                                 //在部门才需要发送短信
                                 if (nowWorkflow != null && order.CenterToOrgTime.HasValue)
                                 {
@@ -131,11 +136,12 @@ namespace Hotline.Api.Controllers
                                         await _mediator.Publish(new PushMessageNotify(messageDto), HttpContext.RequestAborted);
                                     }
                                 }
-
                             }
+
                             #endregion
 
                             #region 处理流程业务
+
                             //处理流程业务
                             //如果开启了流程直接归档,如果没开启流程,开启流程到归档
                             if (string.IsNullOrEmpty(order.WorkflowId))
@@ -150,12 +156,14 @@ namespace Hotline.Api.Controllers
                             }
                             else
                             {
-                                await _workflowApplication.JumpToEndAsync(order.WorkflowId, dto.RevocationReason,
+                                await _workflowApplication.JumpToEndAsync(_sessionContext, order.WorkflowId, dto.RevocationReason,
                                     null, order.ExpiredTime, cancellationToken: HttpContext.RequestAborted);
                             }
+
                             #endregion
 
                             #region 处理工单的一级部门和实际办理部门
+
                             //处理工单的一级部门和实际办理部门
                             var org = await _systemOrganizeRepository.GetAsync(p => p.Id == OrgSeedData.CenterId, HttpContext.RequestAborted);
                             order.ActualHandleOrgAreaCode = org?.AreaCode;
@@ -180,15 +188,14 @@ namespace Hotline.Api.Controllers
                                 it.ActualHandleTime,
                                 it.ActualHandlerId
                             }).ExecuteCommandAsync();
+
                             #endregion
 
-                           
 
                             successNum++;
                         }
                         else
                             errorNum++;
-
                     }
                 }
                 else
@@ -203,7 +210,6 @@ namespace Hotline.Api.Controllers
                 SuccessNum = successNum,
             };
             return responseDto;
-
         }
     }
-}
+}

+ 1 - 1
src/Hotline.Application/FlowEngine/IWorkflowApplication.cs

@@ -66,7 +66,7 @@ namespace Hotline.Application.FlowEngine
         /// <summary>
         /// 跳转至结束节点(无视流程模板配置以及当前办理对象)
         /// </summary>
-        Task JumpToEndAsync(string workflowId, string opinion, List<FileDto> files, DateTime? expiredTime,
+        Task JumpToEndAsync(ISessionContext current,string workflowId, string opinion, List<FileDto> files, DateTime? expiredTime,
             EReviewResult reviewResult = EReviewResult.Unknown, CancellationToken cancellationToken = default);
 
         ////////

+ 97 - 69
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -44,6 +44,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     private readonly IWorkflowDomainService _workflowDomainService;
     private IRepository<WorkflowStep> _workflowStepRepository;
     private IRepository<WorkflowTrace> _workflowTraceRepository;
+    private readonly IRepository<WorkflowCountersign> _workflowCountersignRepository;
     private readonly IRepository<User> _userRepository;
     private readonly ISystemOrganizeRepository _organizeRepository;
     private readonly IRepository<Role> _roleRepository;
@@ -58,6 +59,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         IWorkflowDomainService workflowDomainService,
         IRepository<WorkflowStep> workflowStepRepository,
         IRepository<WorkflowTrace> workflowTraceRepository,
+        IRepository<WorkflowCountersign> workflowCountersignRepository,
         IRepository<User> userRepository,
         ISystemOrganizeRepository organizeRepository,
         IRepository<Role> roleRepository,
@@ -71,6 +73,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         _workflowDomainService = workflowDomainService;
         _workflowStepRepository = workflowStepRepository;
         _workflowTraceRepository = workflowTraceRepository;
+        _workflowCountersignRepository = workflowCountersignRepository;
         _userRepository = userRepository;
         _organizeRepository = organizeRepository;
         _roleRepository = roleRepository;
@@ -441,7 +444,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     /// <summary>
     /// 跳转至结束节点(无视流程模板配置以及当前办理对象,直接跳至结束节点)
     /// </summary>
-    public async Task JumpToEndAsync(string workflowId, string opinion, List<FileDto> files, DateTime? expiredTime,
+    public async Task JumpToEndAsync(ISessionContext current, string workflowId, string opinion, List<FileDto> files, DateTime? expiredTime,
         EReviewResult reviewResult = EReviewResult.Unknown, CancellationToken cancellationToken = default)
     {
         var workflow = await _workflowDomainService.GetWorkflowAsync(workflowId, withDefine: true, withSteps: true,
@@ -467,15 +470,18 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
         var unhandleSteps = workflow.Steps
             .Where(d => d.Status != EWorkflowStepStatus.Handled).ToList();
-
         var unhandleTraces = workflow.Traces
             .Where(d => d.Status != EWorkflowStepStatus.Handled).ToList();
 
-        //todo 结束会签
+        //get currentStep
+        var currentStep = unhandleSteps.MaxBy(d => d.CreationTime)
+                          ?? workflow.Steps.MaxBy(d => d.CreationTime);
 
         foreach (var step in unhandleSteps)
         {
             await _workflowDomainService.HandleStepAsync(step, workflow, dto, null, null, cancellationToken);
+            if (step.IsStartCountersign)
+                step.CountersignEnd();
 
             var trace = unhandleTraces.First(d => d.StepId == step.Id);
             _mapper.Map(dto, trace);
@@ -485,11 +491,29 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
         await _workflowStepRepository.UpdateRangeAsync(unhandleSteps, cancellationToken);
         await _workflowTraceRepository.UpdateRangeAsync(unhandleTraces, cancellationToken);
 
-        if (workflow.Steps.All(d => d.StepType != EStepType.End))
+        //结束会签
+        var counstersigns = await _workflowCountersignRepository.Queryable()
+            .Where(d => !d.IsCompleted())
+            .ToListAsync(cancellationToken);
+        foreach (var counstersign in counstersigns)
         {
-            var currentStep = unhandleSteps.FirstOrDefault()
-                              ?? workflow.Steps.OrderBy(d => d.CreationTime).Last();
+            //结束会签
+            counstersign.End(currentStep.Id, currentStep.Code, currentStep.BusinessType,
+                current.UserId, current.UserName,
+                current.OrgId, current.OrgName,
+                current.OrgAreaCode, current.OrgAreaName);
+        }
+
+        await _workflowCountersignRepository.UpdateRangeAsync(counstersigns, cancellationToken);
+
+
+        //更新实际办理节点信息
+        workflow.UpdateActualStepWhenHandle(currentStep, current.OrgAreaCode, current.OrgAreaName, current.OrgLevel);
+
+        workflow.UpdateCurrentStepWhenHandle(currentStep, current.OrgAreaCode, current.OrgAreaName, current.OrgLevel);
 
+        if (workflow.Steps.All(d => d.StepType != EStepType.End))
+        {
             await _workflowDomainService.EndAsync(workflow, dto,
                 endStepDefine, currentStep, expiredTime, cancellationToken);
         }
@@ -990,7 +1014,7 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     {
                         users1 = users1.Where(d => d.OrgId.StartsWith(levelOneOrgId));
                     }
-                    else if(stepDefine.BusinessType is EBusinessType.DepartmentLeader)
+                    else if (stepDefine.BusinessType is EBusinessType.DepartmentLeader)
                     {
                         users1 = users1.Where(d => d.OrgId == orgId);
                     }
@@ -1305,66 +1329,70 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                     .ToListAsync(cancellationToken);
                 break;
             case EDynamicPolicy.OrgUpLeadCenterTop:
-				orgLevel = _sessionContextProvider.SessionContext.OrgLevel - 1;
-				if (orgLevel < 0) orgLevel = 0;
-				isLead = _sessionContextProvider.SessionContext.Roles.Any(x => x == leadRoleCode);
-				isSkip = await _userRepository.Queryable().AnyAsync(x => x.OrgId == _sessionContextProvider.SessionContext.RequiredOrgId && x.Roles.Any(r => r.Name == leadRoleCode), cancellationToken);
-				if (orgLevel == 0 && (isLead || !isSkip))
-				{
-					businessType = EBusinessType.Send;
-					if (currentBusinessType == EBusinessType.Department)
-						flowDirection = EFlowDirection.OrgToCenter;
-
-					items = await _organizeRepository.Queryable()
-						.Where(d => d.IsCenter)
-						.Select(d => new FlowStepHandler
-						{
-							Key = d.Id,
-							Value = d.Name,
-							OrgId = d.Id,
-							OrgName = d.Name
-						})
-						.ToListAsync(cancellationToken);
-				}
-				else
-				{
-					businessType = EBusinessType.Department;
-					upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(_sessionContextProvider.SessionContext.OrgLevel);
-					if (!isLead)
-					{
-						if (isSkip)
-						{
-							roleId = leadRoleCode;
-							roleName = leadRoleName;
-						}
-					}
-					if (isLead || !isSkip)
-					{
-						//上级部门Id
-						upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
-						roleId = handleRoleCode;
-						roleName = handleRoleName;
-					}
-					else
-					{
-						orgLevel += 1;
-					}
-					items = await _organizeRepository.Queryable()
-						.Where(d => d.Id == upperOrgId)
-						.Select(d => new FlowStepHandler
-						{
-							Key = d.Id,
-							Value = d.Name,
-							OrgId = d.Id,
-							OrgName = d.Name,
-							RoleId = roleId,
-							RoleName = roleName
-						})
-						.ToListAsync(cancellationToken);
-				}
-
-				break;
-			case EDynamicPolicy.OrgUpLead:
+                orgLevel = _sessionContextProvider.SessionContext.OrgLevel - 1;
+                if (orgLevel < 0) orgLevel = 0;
+                isLead = _sessionContextProvider.SessionContext.Roles.Any(x => x == leadRoleCode);
+                isSkip = await _userRepository.Queryable()
+                    .AnyAsync(x => x.OrgId == _sessionContextProvider.SessionContext.RequiredOrgId && x.Roles.Any(r => r.Name == leadRoleCode),
+                        cancellationToken);
+                if (orgLevel == 0 && (isLead || !isSkip))
+                {
+                    businessType = EBusinessType.Send;
+                    if (currentBusinessType == EBusinessType.Department)
+                        flowDirection = EFlowDirection.OrgToCenter;
+
+                    items = await _organizeRepository.Queryable()
+                        .Where(d => d.IsCenter)
+                        .Select(d => new FlowStepHandler
+                        {
+                            Key = d.Id,
+                            Value = d.Name,
+                            OrgId = d.Id,
+                            OrgName = d.Name
+                        })
+                        .ToListAsync(cancellationToken);
+                }
+                else
+                {
+                    businessType = EBusinessType.Department;
+                    upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(_sessionContextProvider.SessionContext.OrgLevel);
+                    if (!isLead)
+                    {
+                        if (isSkip)
+                        {
+                            roleId = leadRoleCode;
+                            roleName = leadRoleName;
+                        }
+                    }
+
+                    if (isLead || !isSkip)
+                    {
+                        //上级部门Id
+                        upperOrgId = _sessionContextProvider.SessionContext.RequiredOrgId.GetHigherOrgId(orgLevel);
+                        roleId = handleRoleCode;
+                        roleName = handleRoleName;
+                    }
+                    else
+                    {
+                        orgLevel += 1;
+                    }
+
+                    items = await _organizeRepository.Queryable()
+                        .Where(d => d.Id == upperOrgId)
+                        .Select(d => new FlowStepHandler
+                        {
+                            Key = d.Id,
+                            Value = d.Name,
+                            OrgId = d.Id,
+                            OrgName = d.Name,
+                            RoleId = roleId,
+                            RoleName = roleName
+                        })
+                        .ToListAsync(cancellationToken);
+                }
+
+                break;
+            case EDynamicPolicy.OrgUpLead:
                 businessType = _sessionContextProvider.SessionContext.OrgIsCenter
                     ? EBusinessType.Send
                     : _sessionContextProvider.SessionContext.RequiredOrgId.CalcOrgLevel() == 1
@@ -1395,10 +1423,10 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
                 }
                 else
                 {
-	                orgLevel += 1;
+                    orgLevel += 1;
                 }
 
-				items = await _organizeRepository.Queryable()
+                items = await _organizeRepository.Queryable()
                     .Where(d => d.Id == upperOrgId)
                     .Select(d => new FlowStepHandler
                     {

+ 9 - 4
src/Hotline.Application/Orders/OrderApplication.cs

@@ -322,9 +322,11 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         //DateTime stTime2 = _timeLimitDomainService.WorkDay(DateTime.Now);
         DateTime? dateTime = DateTime.Now;
         var IsCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
-
+        int orgLevel = _sessionContextProvider.SessionContext.OrgLevel;
+        var orgCode = _sessionContextProvider.SessionContext.OrgId;
         return _orderRepository.Queryable(canView: !IsCenter).Includes(d => d.OrderDelays)
-            .Where(d => SqlFunc.Subqueryable<WorkflowStep>()
+
+            .WhereIF(orgLevel==3,d => SqlFunc.Subqueryable<WorkflowStep>()
                 .Where(step => step.ExternalId == d.Id && step.Status != EWorkflowStepStatus.Handled &&
                                ((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) &&
                                  step.HandlerId == _sessionContextProvider.SessionContext.RequiredUserId) ||
@@ -333,6 +335,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                                 (step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) &&
                                  _sessionContextProvider.SessionContext.Roles.Contains(step.RoleId))))
                 .Any())
+            .WhereIF(orgLevel==2 || orgLevel == 1,d=> d.ActualHandleOrgCode.StartsWith(orgCode))
             .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
             .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No.Contains(dto.No!))
             .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title.Contains(dto.Title!))
@@ -383,9 +386,10 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         // DateTime stTime = _timeLimitDomainService.WorkDay(DateTime.Now);
         DateTime stTime = _expireTime.WorkDay(DateTime.Now).GetAwaiter().GetResult();
         var IsCenter = _sessionContextProvider.SessionContext.OrgIsCenter;
-
+        int orgLevel = _sessionContextProvider.SessionContext.OrgLevel;
+        var orgCode = _sessionContextProvider.SessionContext.OrgId;
         return _orderRepository.Queryable(canView: false).Includes(d => d.OrderDelays)
-            .Where(d => SqlFunc.Subqueryable<WorkflowStep>()
+            .WhereIF(orgLevel == 3,d => SqlFunc.Subqueryable<WorkflowStep>()
                 .Where(step => step.ExternalId == d.Id && step.Status != EWorkflowStepStatus.Handled &&
                                ((step.FlowAssignType == EFlowAssignType.User && !string.IsNullOrEmpty(step.HandlerId) &&
                                  step.HandlerId == _sessionContextProvider.SessionContext.RequiredUserId) ||
@@ -394,6 +398,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                                 (step.FlowAssignType == EFlowAssignType.Role && !string.IsNullOrEmpty(step.RoleId) &&
                                  _sessionContextProvider.SessionContext.Roles.Contains(step.RoleId))))
                 .Any())
+            .WhereIF(orgLevel == 2 || orgLevel == 1, d => d.ActualHandleOrgCode.StartsWith(orgCode))
             .WhereIF(dto.IsProvince.HasValue, d => d.IsProvince == dto.IsProvince)
             //.WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.Contains(dto.Keyword!) || d.No.Contains(dto.Keyword!))
             .WhereIF(!string.IsNullOrEmpty(dto.No), x => x.No.Contains(dto.No))

+ 4 - 4
src/Hotline/FlowEngine/Workflows/IWorkflowDomainService.cs

@@ -155,10 +155,10 @@ namespace Hotline.FlowEngine.Workflows
         /// </summary>
         List<StepDefine> NextStepDefineFilter(EPathPolicy pathPolicy, List<StepDefine> nextStepDefines);
 
-        /// <summary>
-        /// 撤销流程
-        /// </summary>
-        Task CancelAsync(CancelDto dto, DateTime? expiredTime, ISessionContext current, CancellationToken cancellationToken);
+        // /// <summary>
+        // /// 撤销流程
+        // /// </summary>
+        // Task CancelAsync(CancelDto dto, DateTime? expiredTime, ISessionContext current, CancellationToken cancellationToken);
 
         ///// <summary>
         ///// 更新期满时间

+ 23 - 22
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -1773,28 +1773,28 @@ namespace Hotline.FlowEngine.Workflows
             return nextStepDefines;
         }
 
-        /// <summary>
-        /// 撤销流程
-        /// </summary>
-        public async Task CancelAsync(CancelDto dto, DateTime? expiredTime, ISessionContext current,
-            CancellationToken cancellationToken)
-        {
-            var workflow = await GetWorkflowAsync(dto.WorkflowId, withDefine: true, withSteps: true,
-                cancellationToken: cancellationToken);
-
-            var currentStep = GetUnHandleStep(workflow.Steps, _sessionContextProvider.SessionContext.RequiredOrgId,
-                _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.Roles);
-            //var (currentStepBox, currentStep) = GetUnCompleteStep(workflow.Steps, _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.RequiredUserId);
-
-            var endStepDefine = workflow.WorkflowDefinition.FindEndStepDefine();
-
-            var basicDto = _mapper.Map<BasicWorkflowDto>(dto);
-            var endTrace = await EndAsync(workflow, basicDto, endStepDefine, currentStep,
-                expiredTime, cancellationToken: cancellationToken);
-
-            await _publisher.PublishAsync(new CancelWorkflowNotify(workflow), PublishStrategy.ParallelWhenAll,
-                cancellationToken);
-        }
+        // /// <summary>
+        // /// 撤销流程
+        // /// </summary>
+        // public async Task CancelAsync(CancelDto dto, DateTime? expiredTime, ISessionContext current,
+        //     CancellationToken cancellationToken)
+        // {
+        //     var workflow = await GetWorkflowAsync(dto.WorkflowId, withDefine: true, withSteps: true,
+        //         cancellationToken: cancellationToken);
+        //
+        //     var currentStep = GetUnHandleStep(workflow.Steps, _sessionContextProvider.SessionContext.RequiredOrgId,
+        //         _sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.Roles);
+        //     //var (currentStepBox, currentStep) = GetUnCompleteStep(workflow.Steps, _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.RequiredUserId);
+        //
+        //     var endStepDefine = workflow.WorkflowDefinition.FindEndStepDefine();
+        //
+        //     var basicDto = _mapper.Map<BasicWorkflowDto>(dto);
+        //     var endTrace = await EndAsync(workflow, basicDto, endStepDefine, currentStep,
+        //         expiredTime, cancellationToken: cancellationToken);
+        //
+        //     await _publisher.PublishAsync(new CancelWorkflowNotify(workflow), PublishStrategy.ParallelWhenAll,
+        //         cancellationToken);
+        // }
 
         /// <summary>
         /// 新增流程流转记录
@@ -2274,6 +2274,7 @@ namespace Hotline.FlowEngine.Workflows
         /// </summary>
         private void HandleStep(WorkflowStep step, string opinion, string nextStepCode)
         {
+            //todo 重构:ISessionContext传入
             step.Handle(_sessionContextProvider.SessionContext.RequiredUserId, _sessionContextProvider.SessionContext.UserName,
                 _sessionContextProvider.SessionContext.RequiredOrgId, _sessionContextProvider.SessionContext.OrgName,
                 _sessionContextProvider.SessionContext.OrgAreaCode, _sessionContextProvider.SessionContext.OrgAreaName,