Procházet zdrojové kódy

WorkflowCountersign.cs add Members property

xf před 1 rokem
rodič
revize
73f7194d2d

+ 2 - 1
src/Hotline.Application/Handlers/FlowEngine/WorkflowStartHandler.cs

@@ -77,10 +77,11 @@ namespace Hotline.Application.Handlers.FlowEngine
                     var publishCallRecordDto = new PublishCallRecrodDto() { };
                     //查询通话记录
                     var callRecord = await _trCallRecordRepository.GetAsync(order.CallId, cancellationToken);
-                    if (callRecord!=null)
+                    if (callRecord != null)
                     {
                         publishCallRecordDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
                     }
+
                     publishCallRecordDto.Order = _mapper.Map<OrderDto>(order);
 
                     await _capPublisher.PublishAsync(EventNames.HotlineOrderFlowStarted, publishCallRecordDto,

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

@@ -139,12 +139,12 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 		return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
 	}
 
-	/// <summary>
-	/// 即将超期节点列表
-	/// </summary>
-	/// <param name="dto"></param>
-	/// <param name="cancellationToken"></param>
-	/// <returns></returns>
+	// /// <summary>
+	// /// 即将超期节点列表
+	// /// </summary>
+	// /// <param name="dto"></param>
+	// /// <param name="cancellationToken"></param>
+	// /// <returns></returns>
 	//public async Task<PagedDto<WorkflowOrderDto>> GetAboutToExpireNodeAsync(AboutToExpireListDto dto, CancellationToken cancellationToken)
 	//{
 	//	var setting = _systemSettingCacheManager.GetSetting(SettingConstants.OrderAboutToExpire);

+ 0 - 15
src/Hotline.Share/Enums/Order/EProcessType.cs

@@ -14,19 +14,4 @@ public enum EProcessType
     /// 交办
     /// </summary>
     Jiaoban = 20,
-
-    /// <summary>
-    /// 派单员重派
-    /// </summary>
-    PdyChongpai = 30,
-
-    /// <summary>
-    /// 结果审核重派
-    /// </summary>
-    ShChongpai = 40,
-
-    /// <summary>
-    /// 回访不满意重派	
-    /// </summary>
-    HfChongpai = 50
 }

+ 5 - 0
src/Hotline/FlowEngine/Workflows/Workflow.cs

@@ -46,6 +46,11 @@ public partial class Workflow : CreationEntity
     /// 到期时间(期满时间)
     /// </summary>
     public DateTime ExpiredTime { get; set; }
+    
+    /// <summary>
+    /// 即将超期时间
+    /// </summary>
+    public DateTime? NearlyExpiredTime { get; set; }
 
     #region 办理时限
 

+ 30 - 16
src/Hotline/FlowEngine/Workflows/WorkflowCountersign.cs

@@ -1,10 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using Hotline.Share.Dtos;
 using Hotline.Share.Enums.FlowEngine;
 using SqlSugar;
+using XF.Domain.Entities;
+using XF.Domain.Exceptions;
 using XF.Domain.Repository;
 
 namespace Hotline.FlowEngine.Workflows
@@ -99,7 +97,6 @@ namespace Hotline.FlowEngine.Workflows
         /// </summary>
         public DateTime? EndTime { get; set; }
 
-
         #endregion
 
         /// <summary>
@@ -108,21 +105,22 @@ namespace Hotline.FlowEngine.Workflows
         public string? ParentId { get; set; }
 
         /// <summary>
-        /// 该会签参与成员数量
+        /// 会签类型(非工单办理为null)
         /// </summary>
-        public int Members { get; set; }
+        public ECounterSignType? CounterSignType { get; set; }
 
         /// <summary>
-        /// 会签类型
+        /// 该会签参与成员数量
         /// </summary>
-        public ECounterSignType CounterSignType { get; set; }
+        // public int Members { get; set; }
+        [SugarColumn(ColumnDataType = "json", IsJson = true)]
+        public List<CountersignMember>? Members { get; set; }
+        //todo 发起时记录哪些待办,办理时记录哪些已办
 
         /// <summary>
-        /// 发起会签节点设置的期满时间(冗余)
+        /// 流程指派类型(冗余,非工单办理为null)
         /// </summary>
-        public DateTime StartExpiredTime { get; set; }
-
-
+        public EFlowAssignType? FlowAssignType { get; set; }
 
         #region method
 
@@ -136,7 +134,7 @@ namespace Hotline.FlowEngine.Workflows
         /// </summary>
         public void End(
             string endStepId, string endStepCode, EBusinessType businessType,
-            string userId, string? userName, 
+            string userId, string? userName,
             string orgId, string? orgName,
             string? orgAreaCode, string? orgAreaName)
         {
@@ -152,6 +150,22 @@ namespace Hotline.FlowEngine.Workflows
             EndTime = DateTime.Now;
         }
 
+        public void MemberHandled(string userId, string orgId)
+        {
+            var member = FlowAssignType == EFlowAssignType.Org
+                ? Members.FirstOrDefault(d => d.Key == orgId)
+                : Members.FirstOrDefault(d => d.Key == userId);
+
+            if (member is null)
+                throw new UserFriendlyException($"未找到会签办理对象");
+            member.IsHandled = true;
+        }
+        
         #endregion
     }
-}
+
+    public class CountersignMember : Kv
+    {
+        public bool IsHandled { get; set; }
+    }
+}

+ 41 - 25
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -96,8 +96,7 @@ namespace Hotline.FlowEngine.Workflows
         /// 流程开始
         /// </summary>
         public async Task StartAsync(Workflow workflow, WorkflowStep startStep, BasicWorkflowDto dto,
-            StepDefine firstStepDefine,
-            FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
+            StepDefine firstStepDefine, FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
         {
             //1. 创建first节点 (和trace)2.办理开始节点 
 
@@ -109,7 +108,8 @@ namespace Hotline.FlowEngine.Workflows
 
             //办理开始节点
             var counterSignType = GetCounterSignType(startStep.BusinessType);
-            await HandleStepAsync(startStep, workflow, dto, counterSignType, cancellationToken);
+            await HandleStepAsync(startStep, workflow, dto, flowAssignInfo.FlowAssignType, counterSignType,
+                cancellationToken);
             //赋值当前节点的下级办理节点
             if (dto.IsStartCountersign)
                 startStep.CreateCountersignSteps(firstSteps);
@@ -285,11 +285,11 @@ namespace Hotline.FlowEngine.Workflows
 
             var counterSignType = GetCounterSignType(currentStep.BusinessType);
 
-            await HandleStepAsync(currentStep, workflow, dto, counterSignType, cancellationToken);
+            await HandleStepAsync(currentStep, workflow, dto, flowAssignInfo.FlowAssignType, counterSignType,
+                cancellationToken);
 
             currentStep.IsActualHandled = CheckIsActualHandle(workflow, currentStep, nextStepDefine, dto);
 
-            //update realhandle info
             _mapper.Map(dto, workflow);
 
             var updateSteps = new List<WorkflowStep> { currentStep };
@@ -326,20 +326,36 @@ namespace Hotline.FlowEngine.Workflows
                 }
             }
 
-            //操作为回到会签汇总时,更新开始会签节点的会签办理状态
-            if (currentStep.IsInCountersign() && dto.BackToCountersignEnd)
+            if (currentStep.IsInCountersign())
             {
-                if (currentStep.IsCountersignEndStep)
+                //操作为回到会签汇总时,更新开始会签节点的会签办理状态
+                if (dto.BackToCountersignEnd)
                 {
-                    //汇总节点(非顶级)
-                    var csStartStep = workflow.Steps.FirstOrDefault(d => d.Id == currentStep.CountersignStartStepId);
-                    if (csStartStep is null)
-                        throw new UserFriendlyException("未查询到会签开始节点");
-                    PrevStepCsHandled(workflow, csStartStep, ref updateSteps);
+                    if (currentStep.IsCountersignEndStep)
+                    {
+                        //汇总节点(非顶级)
+                        var csStartStep =
+                            workflow.Steps.FirstOrDefault(d => d.Id == currentStep.CountersignStartStepId);
+                        if (csStartStep is null)
+                            throw new UserFriendlyException("未查询到会签开始节点");
+                        PrevStepCsHandled(workflow, csStartStep, ref updateSteps);
+                    }
+                    else
+                    {
+                        PrevStepCsHandled(workflow, currentStep, ref updateSteps);
+                    }
                 }
                 else
                 {
-                    PrevStepCsHandled(workflow, currentStep, ref updateSteps);
+                    //会签中正常办理节点,更新会签members办理状态
+                    var countersign = workflow.Countersigns.FirstOrDefault(d => d.Id == currentStep.CountersignId);
+                    if (countersign is null)
+                        throw new UserFriendlyException(
+                            $"会签数据异常, workflowId: {currentStep.WorkflowId}, countersignId: {currentStep.CountersignId}",
+                            "会签数据异常");
+                    countersign.MemberHandled(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId);
+                    //update cs
+                    await _workflowCountersignRepository.UpdateAsync(countersign, cancellationToken);
                 }
             }
 
@@ -632,7 +648,7 @@ namespace Hotline.FlowEngine.Workflows
         {
             var currentStep = GetUnHandleStep(workflow.Steps, _sessionContext.RequiredOrgId,
                 _sessionContext.RequiredUserId);
-            await HandleStepAsync(currentStep, workflow, dto, null, cancellationToken);
+            await HandleStepAsync(currentStep, workflow, dto, null, null, cancellationToken);
 
             var endStepDefine = workflow.WorkflowDefinition.FindEndStepDefine();
             var endTrace = await EndAsync(workflow, dto, endStepDefine, currentStep, EReviewResult.Failed,
@@ -1036,7 +1052,7 @@ namespace Hotline.FlowEngine.Workflows
         /// 办理节点
         /// </summary>
         private async Task HandleStepAsync(WorkflowStep step, Workflow workflow, BasicWorkflowDto dto,
-            ECounterSignType? counterSignType, CancellationToken cancellationToken)
+            EFlowAssignType? flowAssignType, ECounterSignType? counterSignType, CancellationToken cancellationToken)
         {
             if (step.Status is EWorkflowStepStatus.Handled)
                 throw UserFriendlyException.SameMessage("当前节点状态已办理");
@@ -1049,7 +1065,7 @@ namespace Hotline.FlowEngine.Workflows
 
             //创建会签数据
             if (dto.IsStartCountersign)
-                await StartCountersignAsync(workflow, step, dto, counterSignType.Value, cancellationToken);
+                await StartCountersignAsync(workflow, step, dto, flowAssignType, counterSignType, cancellationToken);
 
             //办理参数
             _mapper.Map(dto, step);
@@ -1058,7 +1074,8 @@ namespace Hotline.FlowEngine.Workflows
             HandleStep(step, dto.NextStepCode);
         }
 
-        private bool CheckIsActualHandle(Workflow workflow, WorkflowStep step, StepDefine nextStepDefine, BasicWorkflowDto dto)
+        private bool CheckIsActualHandle(Workflow workflow, WorkflowStep step, StepDefine nextStepDefine,
+            BasicWorkflowDto dto)
         {
             //1. workflow是否为办理类型 2. 非会签:当前是否为普通节点and下一节点是否为汇总 or endStep 3. 会签:当前操作为汇总还是继续往下办理?thk: 汇总以后但未回到top又往下办理的场景,前面实际办理部门也算作办理部门
             if (workflow.FlowType is not EFlowType.Handle) return false;
@@ -1090,10 +1107,10 @@ namespace Hotline.FlowEngine.Workflows
         /// 开始会签(创建会签数据,更新currentStep会签数据)
         /// </summary>
         private async Task StartCountersignAsync(Workflow workflow, WorkflowStep startStep, BasicWorkflowDto dto,
-            ECounterSignType counterSignType, CancellationToken cancellationToken)
+            EFlowAssignType? flowAssignType, ECounterSignType? counterSignType, CancellationToken cancellationToken)
         {
             var countersign = await CreateCountersignAsync(
-                workflow.Id, startStep, dto.NextHandlers.Count,
+                workflow.Id, startStep, dto.NextHandlers, flowAssignType,
                 counterSignType, startStep.StepExpiredTime.Value,
                 startStep.CountersignId, cancellationToken);
             startStep.StartCountersign(countersign.Id);
@@ -1183,9 +1200,8 @@ namespace Hotline.FlowEngine.Workflows
         }
 
         private async Task<WorkflowCountersign> CreateCountersignAsync(
-            string workflowId, WorkflowStep startStep, int memberCount,
-            ECounterSignType counterSignType, DateTime stepExpiredTime,
-            string? parentId = null,
+            string workflowId, WorkflowStep startStep, List<Kv> handlers, EFlowAssignType? flowAssignType,
+            ECounterSignType? counterSignType, DateTime stepExpiredTime, string? parentId = null,
             CancellationToken cancellationToken = default)
         {
             var countersign = new WorkflowCountersign
@@ -1203,9 +1219,9 @@ namespace Hotline.FlowEngine.Workflows
                 StarterOrgAreaName = _sessionContext.OrgAreaName,
 
                 ParentId = parentId,
-                Members = memberCount,
+                Members = _mapper.Map<List<CountersignMember>>(handlers),
+                FlowAssignType = flowAssignType,
                 CounterSignType = counterSignType,
-                StartExpiredTime = stepExpiredTime,
             };
             await _workflowCountersignRepository.AddAsync(countersign, cancellationToken);
             return countersign;

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

@@ -284,7 +284,7 @@ namespace Hotline.Orders
         public DateTime? StartTime { get; set; }
 
         /// <summary>
-        /// 超期时间
+        /// 超期时间(期满时间)
         /// </summary>
         public DateTime? ExpiredTime { get; set; }
 

+ 12 - 11
src/Hotline/README.md

@@ -1,19 +1,20 @@
 #### 代码编写规范
 
 ##### 1. 参照微软推荐编码规范及约定
-https://docs.microsoft.com/zh-cn/dotnet/csharp/fundamentals/coding-style/identifier-names
-https://docs.microsoft.com/zh-cn/dotnet/csharp/fundamentals/coding-style/coding-conventions
-https://docs.microsoft.com/zh-cn/dotnet/standard/design-guidelines/naming-guidelines
+* https://docs.microsoft.com/zh-cn/dotnet/csharp/fundamentals/coding-style/identifier-names
+* https://docs.microsoft.com/zh-cn/dotnet/csharp/fundamentals/coding-style/coding-conventions
+* https://docs.microsoft.com/zh-cn/dotnet/standard/design-guidelines/naming-guidelines
 
 ##### 2. 该项目扩展规范
 * 枚举:命名以大写E为前缀,在文件列表中可以一目了然
-* 方法命名方式: 
-新增:Addxxx 
-删除:Removexxx 
-修改:Updatexxx 
+* 方法命名方式:
+
+新增:Addxxx  
+删除:Removexxx  
+修改:Updatexxx  
 查询单条数据:Getxxx 
-查询多条数据:Queryxxx 
-查询所有数据:QueryAllxxx 
-异步方法以Async为后缀:GetxxxAsync 
+查询多条数据:Queryxxx  
+查询所有数据:QueryAllxxx  
+异步方法以Async为后缀:GetxxxAsync  
 * WebApi和Web项目的Action都尽量采用异步方法,但命名不加Async后缀(因为此处的调用方不以Action命名来调用,而是以路由规则来访问)
-* 字段以'_'加小写字母为前缀:_orderDomainService
+* 字段以'_'加小写字母为前缀,如:_orderDomainService