Pārlūkot izejas kodu

Merge branch 'master' of http://110.188.24.182:10023/Fengwo/hotline

田爽 1 gadu atpakaļ
vecāks
revīzija
88ce66e0a7

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

@@ -94,7 +94,7 @@ namespace Hotline.Api.Controllers
         [HttpPost("on-duty")]
         public async Task<TrOnDutyResponseDto> OnDuty([FromBody] TrOnDutyDto dto)
         {
-            return await _userDomainService.TrOnDutyAsync(_sessionContext.RequiredUserId, dto.TelId, dto.TelNo, HttpContext.RequestAborted);
+            return await _userDomainService.TrOnDutyAsync(_sessionContext.RequiredUserId, dto.TelId, dto.TelNo,dto.TelPwd,dto.Description, HttpContext.RequestAborted);
         }
 
         /// <summary>

+ 3 - 1
src/Hotline.Api/Controllers/SettingController.cs

@@ -149,7 +149,9 @@ namespace Hotline.Api.Controllers
             if (model is null)
                 throw UserFriendlyException.SameMessage("未知配置,请刷新界面");
 
-            model = _mapper.Map<SystemSetting>(dto);
+            model.SettingValue = dto.SettingValue;
+            model.Sort = dto.Sort;
+            model.Remark = dto.Remark;
             _systemSettingCacheManager.DelSystemSetting(model.Code);
             await _systemSettingsRepository.UpdateAsync(model, HttpContext.RequestAborted);
         }

+ 17 - 9
src/Hotline.Application/FlowEngine/WorkflowApplication.cs

@@ -437,13 +437,19 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
 
         if (currentStep.IsInCountersign())
         {
-            var countersignEndOption = CreateCountersignEndStep(workflow.Steps, currentStep);
-
             if (currentStep.IsCountersignEndStep)
             {
                 //当前待办节点为会签汇总节点时:检查是否为顶级会签发起节点(csstate==none),t:按配置往下走,f:继续往上汇总,不需要重复往下指派
                 if (currentStep.CountersignStartStepId != workflow.TopCountersignStepId)
                 {
+                    //查找当前节点对应会签开始节点的上级作为下一个cs汇总节点的汇总对象
+                    var startCountersignStep = workflow.Steps.FirstOrDefault(d => d.Id == currentStep.CountersignStartStepId);
+                    if (startCountersignStep is null)
+                        throw new UserFriendlyException(
+                            $"未查询到会签开始节点,workflowId: {workflow.Id}, startStepId: {currentStep.CountersignStartStepId}",
+                            "未查询到会签开始节点,数据异常");
+                    var countersignEndOption = CreateCsEndStepByPrev(workflow.Steps, startCountersignStep);
+
                     countersignEndOption.InputRealHandler = true;
                     dto.Steps = new List<NextStepOption> { countersignEndOption };
                     return dto;
@@ -462,6 +468,8 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
             }
             else
             {
+                //汇总节点
+                var countersignEndOption = CreateCsEndStepByPrev(workflow.Steps, currentStep);
                 //按会签策略
                 var nextStepOption = await CreateDynamicStepAsync(currentStep.CountersignPolicy.Value, cancellationToken);
                 dto.Steps = new List<NextStepOption> { nextStepOption, countersignEndOption };
@@ -777,20 +785,20 @@ public class WorkflowApplication : IWorkflowApplication, IScopeDependency
     }
 
 
-    private NextStepOption CreateCountersignEndStep(List<WorkflowStep> steps, WorkflowStep step)
+    private NextStepOption CreateCsEndStepByPrev(List<WorkflowStep> steps, WorkflowStep step)
     {
-        var parentStep = steps.FirstOrDefault(d => d.Id == step.PrevStepId);
-        if (parentStep is null)
+        var prevStep = steps.FirstOrDefault(d => d.Id == step.PrevStepId);
+        if (prevStep is null)
             throw new UserFriendlyException("未查找到会签上级节点");
-        var text = parentStep.HandlerOrgIsCenter.Value
+        var text = prevStep.HandlerOrgIsCenter.Value
             ? "热线中心汇总"
-            : $"{parentStep.HandlerOrgId.CalcOrgLevel().ToChinese()}级部门汇总";
+            : $"{prevStep.HandlerOrgId.CalcOrgLevel().ToChinese()}级部门汇总";
         return new NextStepOption
         {
-            Key = parentStep.Code,
+            Key = prevStep.Code,
             Value = text,//parentStep.Name,//todo name不对,目前为definition.name,需改为x级部门办理
             BackToCountersignEnd = true,
-            Items = new List<Kv> { new(parentStep.HandlerId, parentStep.HandlerName) },
+            Items = new List<Kv> { new(prevStep.HandlerId, prevStep.HandlerName) },
         };
     }
 

+ 4 - 0
src/Hotline.Share/Dtos/TrCallCenter/TrTelDao.cs

@@ -64,6 +64,8 @@ namespace Hotline.Share.Dtos.TrCallCenter
     {
         public string? TelId { get; set; }
         public string? TelNo { get; set; }
+        public string? TelPwd { get; set; }
+        public string? Description { get; set; }
     }
 
     public class TrOnDutyResponseDto
@@ -71,6 +73,8 @@ namespace Hotline.Share.Dtos.TrCallCenter
         public string? TelNo { get; set; }
 
         public string? TelPwd { get; set; }
+
+        public string? Description { get; set; }
     }
 
 

+ 6 - 1
src/Hotline.Share/Requests/SettingsRequest.cs

@@ -23,9 +23,14 @@ namespace Hotline.Share.Requests
         public string Remark { get; set; }
     }
 
-    public record class ModifySettingDto:AddSettingDto
+    public record class ModifySettingDto
     {
         public string Id { get; set; }
+
+        public string Remark { get; set; }
+
+        public int Sort { get; set; }
+        public List<string> SettingValue { get; set; }
     }
 
 

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

@@ -224,6 +224,11 @@ public abstract class StepBasicEntity : CreationEntity
     /// </summary>
     public DateTime? StepExpiredTime { get; set; }
 
+    /// <summary>
+    /// 发起会签
+    /// </summary>
+    public bool IsStartCountersign { get; set; }
+
     #endregion
 
     #region method

+ 100 - 27
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -253,7 +253,7 @@ namespace Hotline.FlowEngine.Workflows
             var currentStep = GetUnHandleStep(workflow.Steps, _sessionContext.RequiredOrgId, _sessionContext.RequiredUserId);
             if (currentStep.Status is not EWorkflowStepStatus.WaitForAccept) return;
 
-            if(currentStep.HandlerType is EHandlerType.AssignedOrg or EHandlerType.OrgLevel or EHandlerType.OrgType
+            if (currentStep.HandlerType is EHandlerType.AssignedOrg or EHandlerType.OrgLevel or EHandlerType.OrgType
                || (currentStep.InstanceMode is EInstanceMode.Dynamic && !currentStep.DynamicShouldTerminal())//动态并且非结束节点
                    || (currentStep.IsInCountersign() && !currentStep.IsCountersignEndStep)//会签并且非会签节点
                    )
@@ -368,7 +368,7 @@ namespace Hotline.FlowEngine.Workflows
                 var countersignStartStep = workflow.Steps.FirstOrDefault(d => d.Id == currentStep.PrevStepId);
                 if (countersignStartStep is null)
                     throw new UserFriendlyException("未查询到会签开始节点");
-                if (!countersignStartStep.HasStartedCountersign())
+                if (!countersignStartStep.IsStartCountersign)
                     throw new UserFriendlyException("查询到会签开始节点状态异常");
 
                 countersignStartStep.CountersignSteps.First(d => d.StepId == currentStep.Id).Completed = true;
@@ -415,7 +415,7 @@ namespace Hotline.FlowEngine.Workflows
             var nextSteps = await CreateNextStepsAsync(workflow, nextStepDefine, currentStep, dto, expiredTime, cancellationToken);
 
             //赋值当前节点的下级办理节点
-            if (dto.IsStartCountersign)
+            if (currentStep.IsInCountersign())
             {
                 currentStep.CreateCountersignSteps(nextSteps);
                 await _workflowStepRepository.UpdateAsync(currentStep, cancellationToken);
@@ -462,34 +462,107 @@ namespace Hotline.FlowEngine.Workflows
             List<WorkflowStep> nextSteps = new();
             if (currentStep.IsInCountersign())
             {
-                if (dto.BackToCountersignEnd)
-                {
-                    var countersignStartStep = workflow.Steps.FirstOrDefault(d => d.Id == currentStep.PrevStepId);
-                    if (countersignStartStep is null)
-                        throw new UserFriendlyException("未查询到会签开始节点");
-                    if (!countersignStartStep.HasStartedCountersign())
-                        throw new UserFriendlyException("查询到会签开始节点状态异常");
-                    //会签未全部办理则不创建汇总节点
-                    if (countersignStartStep.StartedCountersignHasAllHandled()
-                        && !workflow.Steps.Any(d => d.IsCountersignEndStep && d.CountersignStartStepId == countersignStartStep.Id))
-                    {
-                        //todo 创建会签汇总节点
-                        var countersignEndStep = await CreateCountersignEndStepAsync(countersignStartStep, dto, cancellationToken);
-                        nextSteps = new List<WorkflowStep> { countersignEndStep };
+                //if (dto.BackToCountersignEnd)
+                //{
+                //    var countersignStartStep = workflow.Steps.FirstOrDefault(d => d.Id == currentStep.PrevStepId);
+                //    if (countersignStartStep is null)
+                //        throw new UserFriendlyException("未查询到会签开始节点");
+                //    if (!countersignStartStep.HasStartedCountersign())
+                //        throw new UserFriendlyException("查询到会签开始节点状态异常");
+                //    //会签未全部办理则不创建汇总节点
+                //    if (countersignStartStep.StartedCountersignHasAllHandled()
+                //        && !workflow.Steps.Any(d => d.IsCountersignEndStep && d.CountersignStartStepId == countersignStartStep.Id))
+                //    {
+                //        //todo 创建会签汇总节点
+                //        var countersignEndStep = await CreateCountersignEndStepAsync(countersignStartStep, dto, cancellationToken);
+                //        nextSteps = new List<WorkflowStep> { countersignEndStep };
 
-                        //create trace
-                        await CreateTraceAsync(workflow, countersignEndStep, EWorkflowTraceStatus.Normal, cancellationToken);
+                //        //create trace
+                //        await CreateTraceAsync(workflow, countersignEndStep, EWorkflowTraceStatus.Normal, cancellationToken);
 
-                        await _mediator.Publish(new CountersignEndAssigned(workflow), cancellationToken);
+                //        await _mediator.Publish(new CountersignEndAssigned(workflow), cancellationToken);
+                //    }
+                //}
+                //else
+                //{
+                //    //todo 依据会签策略创建会签下一级节点
+                //    //考虑没有下级部门情况
+                //    nextSteps = await CreateStepsAsync(workflow, nextStepDefine, currentStep, dto, dto.NextHandlers,
+                //        EWorkflowStepStatus.WaitForAccept, currentStep.GetNextStepCountersignPosition(),
+                //        expiredTime, false, cancellationToken);
+                //}
+
+                if (currentStep.IsCountersignEndStep)
+                {
+                    //todo check if current is topend f: csStartStep.prev
+                    //todo t: check if dto.StartCs t: csconfig f: config
+                    if (currentStep.CountersignStartStepId == workflow.TopCountersignStepId)
+                    {
+                        if (dto.IsStartCountersign)
+                        {
+                            //todo 依据会签策略创建会签下一级节点
+                            nextSteps = await CreateStepsAsync(workflow, nextStepDefine, currentStep, dto, dto.NextHandlers,
+                                EWorkflowStepStatus.WaitForAccept, currentStep.GetNextStepCountersignPosition(),
+                                expiredTime, false, cancellationToken);
+                        }
+                        else
+                        {
+                            //todo 创建普通节点(根据配置)
+                            nextSteps = await CreateStepsByDefineAsync(workflow, nextStepDefine, currentStep, dto, expiredTime, cancellationToken);
+                        }
+                    }
+                    else
+                    {
+                        //todo csStartStep.prev
+                        var csStartStep =
+                            workflow.Steps.FirstOrDefault(d => d.Id == currentStep.CountersignStartStepId);
+                        if (csStartStep is null)
+                            throw new UserFriendlyException("未查询到会签节点");
+                        var prevStep = workflow.Steps.FirstOrDefault(d => d.Id == csStartStep.PrevStepId);
+                        if (prevStep is null)
+                            throw new UserFriendlyException("未查询到当前节点上级节点");
+                        //会签未全部办理则不创建汇总节点
+                        if (prevStep.StartedCountersignHasAllHandled())
+                        {
+                            //todo 创建会签汇总节点
+                            var countersignEndStep = await CreateCountersignEndStepAsync(prevStep, dto, cancellationToken);
+                            nextSteps = new List<WorkflowStep> { countersignEndStep };
+
+                            //create trace
+                            await CreateTraceAsync(workflow, countersignEndStep, EWorkflowTraceStatus.Normal, cancellationToken);
+
+                            await _mediator.Publish(new CountersignEndAssigned(workflow), cancellationToken);
+                        }
                     }
                 }
                 else
                 {
-                    //todo 依据会签策略创建会签下一级节点
-                    //考虑没有下级部门情况
-                    nextSteps = await CreateStepsAsync(workflow, nextStepDefine, currentStep, dto, dto.NextHandlers,
-                        EWorkflowStepStatus.WaitForAccept, currentStep.GetNextStepCountersignPosition(),
-                        expiredTime, false, cancellationToken);
+                    if (dto.BackToCountersignEnd)
+                    {
+                        //todo check if cs all complete, create next
+                        var prevStep = workflow.Steps.FirstOrDefault(d => d.Id == currentStep.PrevStepId);
+                        if (prevStep is null)
+                            throw new UserFriendlyException("未查询到当前节点上级节点");
+                        //会签未全部办理则不创建汇总节点
+                        if (prevStep.StartedCountersignHasAllHandled())
+                        {
+                            //todo 创建会签汇总节点
+                            var countersignEndStep = await CreateCountersignEndStepAsync(prevStep, dto, cancellationToken);
+                            nextSteps = new List<WorkflowStep> { countersignEndStep };
+
+                            //create trace
+                            await CreateTraceAsync(workflow, countersignEndStep, EWorkflowTraceStatus.Normal, cancellationToken);
+
+                            await _mediator.Publish(new CountersignEndAssigned(workflow), cancellationToken);
+                        }
+                    }
+                    else
+                    {
+                        //todo 依据会签策略创建会签下一级节点
+                        nextSteps = await CreateStepsAsync(workflow, nextStepDefine, currentStep, dto, dto.NextHandlers,
+                            EWorkflowStepStatus.WaitForAccept, currentStep.GetNextStepCountersignPosition(),
+                            expiredTime, false, cancellationToken);
+                    }
                 }
             }
             else if (dto.IsStartCountersign)
@@ -519,7 +592,6 @@ namespace Hotline.FlowEngine.Workflows
             BasicWorkflowDto dto, CancellationToken cancellationToken)
         {
             var csEndStep = _mapper.Map<WorkflowStep>(countersignStartStep);
-            _mapper.Map(dto, csEndStep);
             csEndStep.Status = EWorkflowStepStatus.WaitForAccept;
             csEndStep.NextSteps = new();
             csEndStep.PrevStepId = null;
@@ -535,6 +607,7 @@ namespace Hotline.FlowEngine.Workflows
             csEndStep.TimeLimit = GetTimeLimit(""); //todo 过期时间
 
             csEndStep.Reset();
+            csEndStep.ResetParameters();
 
             await _workflowStepRepository.AddAsync(csEndStep, cancellationToken);
             return csEndStep;
@@ -1432,7 +1505,7 @@ namespace Hotline.FlowEngine.Workflows
             CancellationToken cancellationToken
             )
         {
-            var countersignId = prevStep.HasStartedCountersign() ? prevStep.StartCountersignId : prevStep.CountersignId;
+            var countersignId = prevStep.IsStartCountersign ? prevStep.StartCountersignId : prevStep.CountersignId;
 
             List<WorkflowStep> steps = new();
             if (dto.IsStartCountersign)

+ 32 - 15
src/Hotline/FlowEngine/Workflows/WorkflowStep.cs

@@ -16,7 +16,7 @@ public class WorkflowStep : StepBasicEntity
     public List<StepSimple> NextSteps { get; set; } = new();
 
     /// <summary>
-    /// 前一级节点Id(stepBox此字段为上级stepBoxId,step为上级stepId),汇总节点无此字段(因可能有多个上级来源)
+    /// 前一级节点Id,会签汇总节点无此字段(因可能有多个上级来源)
     /// </summary>
     public string? PrevStepId { get; set; }
     public string? PrevStepCode { get; set; }
@@ -57,17 +57,11 @@ public class WorkflowStep : StepBasicEntity
 
     /// <summary>
     /// 节点处于会签流程中的位置(区别直接办理会签和会签内非会签节点)
+    /// outer属于特殊会签
     /// 最顶层的发起会签节点为none
     /// </summary>
     public ECountersignPosition CountersignPosition { get; set; }
 
-    #region 发起会签节点特有
-
-    /// <summary>
-    /// 发起会签生成会签Id(不发起会签节点无此字段)
-    /// </summary>
-    public string? StartCountersignId { get; set; }
-
     /// <summary>
     /// 会签直属办理节点
     /// </summary>
@@ -79,6 +73,13 @@ public class WorkflowStep : StepBasicEntity
     /// </summary>
     public bool IsStartedCountersignEnd { get; set; }
 
+    #region 发起会签节点特有
+
+    /// <summary>
+    /// 发起会签生成会签Id(不发起会签节点无此字段)
+    /// </summary>
+    public string? StartCountersignId { get; set; }
+
     #endregion
 
     #region 会签汇总节点特有
@@ -104,10 +105,10 @@ public class WorkflowStep : StepBasicEntity
     /// </summary>
     public bool IsInCountersign() => CountersignPosition != ECountersignPosition.None;
 
-    /// <summary>
-    /// 是否发起过会签
-    /// </summary>
-    public bool HasStartedCountersign() => !string.IsNullOrEmpty(StartCountersignId);
+    ///// <summary>
+    ///// 是否发起过会签
+    ///// </summary>
+    //public bool HasStartedCountersign() => !string.IsNullOrEmpty(StartCountersignId);
 
     /// <summary>
     /// 接办
@@ -171,7 +172,7 @@ public class WorkflowStep : StepBasicEntity
     /// </summary>
     /// <returns></returns>
     public ECountersignPosition GetNextStepCountersignPosition() =>
-        HasStartedCountersign()
+        IsStartCountersign
             ? ECountersignPosition.Inner
             : IsInCountersign()
                 ? ECountersignPosition.Outer
@@ -203,14 +204,30 @@ public class WorkflowStep : StepBasicEntity
         AcceptTime = null;
     }
 
+    /// <summary>
+    /// 重置办理参数
+    /// </summary>
+    public void ResetParameters()
+    {
+        NextHandlers = new();
+        NextMainHandler = null;
+        NextStepCode = null;
+        BackToCountersignEnd = false;
+        IsSms = false;
+        Opinion = null;
+        Additions = new();
+        StepExpiredTime = null;
+    }
+
     /// <summary>
     /// 发起会签节点发起的会签是否全都办理完成
     /// </summary>
     /// <returns></returns>
     public bool StartedCountersignHasAllHandled()
     {
-        if (!HasStartedCountersign())
-            throw new UserFriendlyException("该节点未发起会签");
+        //if (!HasStartedCountersign())
+        //    throw new UserFriendlyException("该节点未发起会签");
+        //outer的情况也属于特殊会签
         return CountersignSteps.All(d => d.Completed);
     }
 

+ 2 - 1
src/Hotline/Users/IUserDomainService.cs

@@ -32,7 +32,8 @@ namespace Hotline.Users
         /// <param name="TelNo"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        Task<TrOnDutyResponseDto> TrOnDutyAsync(string userId, string? TelId, string? TelNo, CancellationToken cancellationToken);
+
+        Task<TrOnDutyResponseDto> TrOnDutyAsync(string userId, string? TelId, string? TelNo,string? TelPwd,string? Description, CancellationToken cancellationToken);
 
         /// <summary>
         /// 下班

+ 16 - 9
src/Hotline/Users/UserDomainService.cs

@@ -123,8 +123,14 @@ namespace Hotline.Users
         /// <param name="TelNo"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        public async Task<TrOnDutyResponseDto> TrOnDutyAsync(string userId,string? TelId,string? TelNo,CancellationToken cancellationToken)
+        public async Task<TrOnDutyResponseDto> TrOnDutyAsync(string userId, string? TelId, string? TelNo, string? TelPwd, string? Description,CancellationToken cancellationToken)
         {
+            var workingTel = await _workRepository.GetCurrentWorkByUserAsync(userId, cancellationToken);
+            if (workingTel is not null)
+            {
+                return new TrOnDutyResponseDto() { TelNo = workingTel.TelNo, TelPwd = workingTel.TelPwd, Description = workingTel.Description };
+            }
+
             //检查配置
             bool IsNeedTelNo = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsNeedTelNo).SettingValue[0]);
             if (IsNeedTelNo && string.IsNullOrEmpty(TelNo))
@@ -147,23 +153,24 @@ namespace Hotline.Users
                 var telModel = await _trClient.QueryTelsAsync(new Tr.Sdk.Tels.QueryTelRequest() { TelNo = TelNo }, cancellationToken);
                 TelId = telModel[0].Id;
                 rsp.TelPwd = telModel[0].Password;
+                rsp.Description = telModel[0].Description;
             }
-            if (!IsNeedTelNo || !IsTelNeedVerify)
-            {
-                rsp.TelPwd = string.Empty;
-            }
+            
 
             rsp.TelNo = TelNo;
-            var workingTel = await _workRepository.GetCurrentWorkByUserAsync(userId, cancellationToken);
-            if (workingTel is not null)
-                throw UserFriendlyException.SameMessage($"当前用户已上班,userId:{userId}");
+          
 
             var telIsWorking = await _workRepository.AnyAsync(d => d.TelId == TelId && !d.EndTime.HasValue, cancellationToken);
             if (telIsWorking)
                 throw UserFriendlyException.SameMessage("当前分机已被占用");
 
-            var work = new Work(userId, user.Name, TelId, TelNo);
+            var work = new Work(userId, user.Name, TelId, TelNo,rsp.TelPwd,rsp.Description);
             await _workRepository.AddAsync(work, cancellationToken);
+
+            if (IsTelNeedVerify)
+            {
+                rsp.TelPwd = string.Empty;
+            }
             return rsp;
         }
 

+ 16 - 0
src/Hotline/Users/Work.cs

@@ -41,6 +41,11 @@ public class Work : CreationModificationEntity
     [SugarColumn(ColumnDescription = "工作时长(单位:秒)")]
     public double? WorkingDuration { get; private set; }
 
+    [SugarColumn(IsIgnore = true)]
+    public string? TelPwd { get; set; }
+
+    [SugarColumn(IsIgnore = true)]
+    public string? Description { get; set; }
     ///// <summary>
     ///// SignalR.ConnectionId
     ///// </summary>
@@ -52,6 +57,17 @@ public class Work : CreationModificationEntity
 
     }
 
+    public Work(string userId, string name, string telId, string telNo, string? telPwd, string? description)
+    {
+        StartTime = DateTime.Now;
+        UserId = userId;
+        UserName = name;
+        TelId = telId;
+        TelNo = telNo;
+        TelPwd = telPwd;
+        Description = description;
+    }
+
     public Work(string userId, string name, string telId, string telNo)
     {
         StartTime = DateTime.Now;