123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- using Hotline.File;
- using Hotline.Share.Dtos;
- using Hotline.Share.Dtos.FlowEngine;
- using Hotline.Share.Dtos.FlowEngine.Definition;
- using Hotline.Share.Dtos.FlowEngine.Workflow;
- using Hotline.Share.Enums.FlowEngine;
- using SqlSugar;
- using XF.Domain.Entities;
- using XF.Domain.Exceptions;
- namespace Hotline.FlowEngine.Workflows;
- public class WorkflowStep : StepBasicEntity
- {
- [Navigate(NavigateType.ManyToOne, nameof(WorkflowId))]
- public Workflow Workflow { get; set; }
- [Navigate(NavigateType.OneToOne, nameof(Id),
- nameof(Workflows.WorkflowTrace.StepId))]
- public WorkflowTrace WorkflowTrace { get; set; }
- //[Navigate(NavigateType.OneToMany, nameof(WorkflowStepHandler.WorkflowStepId))]
- //public List<WorkflowStepHandler> StepHandlers { get; set; }
- #region Method
- /// <summary>
- /// 是否处于会签流程中(不包含顶层发起会签节点)
- /// </summary>
- public bool IsInCountersign() => CountersignPosition != ECountersignPosition.None;
- ///// <summary>
- ///// 是否发起过会签
- ///// </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 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>
- /// 会签结束
- /// </summary>
- public void CountersignEnd() => IsStartedCountersignEnd = true;
- //public void CreateCountersignSteps(List<WorkflowStep> nextSteps) =>
- // CountersignSteps = nextSteps
- // .Select(d => new CountersignStep { StepId = d.Id })
- // .ToList();
- /// <summary>
- /// step设置为可接办状态
- /// </summary>
- public void SetAssigned() => Status = EWorkflowStepStatus.WaitForAccept;
- ///// <summary>
- ///// 依据当前节点获取下一节点会签状态
- ///// </summary>
- ///// <returns></returns>
- //public ECountersignPosition GetNextStepCountersignPosition() =>
- // IsStartCountersign
- // ? ECountersignPosition.Multi
- // : IsInCountersign()
- // ? ECountersignPosition.Single
- // : ECountersignPosition.None;
- public bool IsCenter() => BusinessType is EBusinessType.Seat or EBusinessType.Send;
- public bool IsOrg() => BusinessType is EBusinessType.Department;
- /// <summary>
- /// 重置节点,只清除办理痕迹(退回场景/依据会签开始节点复制会签汇总节点,将上一级节点重置等待重新办理)
- /// </summary>
- public void Reset()
- {
- HandleTime = null;
- AcceptorId = null;
- AcceptorName = null;
- AcceptorOrgId = null;
- AcceptorOrgName = null;
- AcceptorOrgAreaCode = null;
- AcceptorOrgAreaName = null;
- AcceptTime = null;
- IsStartCountersign = false;
- NextSteps.ForEach(d => d.Selected = false);
- }
- /// <summary>
- /// 重置办理参数
- /// </summary>
- public void ResetParameters()
- {
- NextHandlers = new();
- NextMainHandler = null;
- NextStepCode = null;
- BackToCountersignEnd = false;
- IsSms = false;
- Opinion = null;
- FileJson = new();
- IsStartCountersign = false;
- }
- ///// <summary>
- ///// 发起会签节点发起的会签是否全都办理完成
- ///// </summary>
- ///// <returns></returns>
- //public bool StartedCountersignHasAllHandled()
- //{
- // //if (!HasStartedCountersign())
- // // throw new UserFriendlyException("该节点未发起会签");
- // //outer属于特殊会签
- // return CountersignSteps.All(d => d.Completed);
- //}
- /// <summary>
- /// 动态实例化节点是否应该终止
- /// </summary>
- /// <returns></returns>
- public bool DynamicShouldTerminal() => !string.IsNullOrEmpty(NextStepCode) && TerminalDynamicMark == NextStepCode;
- /// <summary>
- /// 是否是顶级会签汇总节点
- /// </summary>
- public bool IsTopCountersignEndStep(string? topCountersignStepId)
- {
- // if (string.IsNullOrEmpty(topCountersignStepId))
- // throw new UserFriendlyException($"无效顶级会签节点编号,wfId: {WorkflowId}");
- return IsCountersignEndStep
- && !string.IsNullOrEmpty(topCountersignStepId)
- && CountersignStartStepId == topCountersignStepId;
- }
- //public WorkflowStepHandler?
- // FindActualHandler(ICollection<string> roles, string? userId = null, string? orgId = null) =>
- // StepHandlers.FirstOrDefault(d => d.IsHandler(roles, userId, orgId));
- //public WorkflowStepHandler? GetActualHandler() =>
- // StepHandlers.FirstOrDefault(d => d.IsActualHandler);
- public bool IsCanHandle(string userId, string orgId, string[] roleIds)
- {
- if(Status is EWorkflowStepStatus.Handled) return false;
- return FlowAssignType switch
- {
- EFlowAssignType.Org => !string.IsNullOrEmpty(HandlerOrgId) && HandlerOrgId == orgId,
- EFlowAssignType.User => !string.IsNullOrEmpty(HandlerId) && HandlerId == userId,
- EFlowAssignType.Role => !string.IsNullOrEmpty(RoleId) && roleIds.Contains(RoleId),
- EFlowAssignType.OrgAndRole => !string.IsNullOrEmpty(HandlerOrgId) && HandlerOrgId == orgId && !string.IsNullOrEmpty(RoleId) && roleIds.Contains(RoleId),
- _ => throw new ArgumentOutOfRangeException()
- };
- }
- #endregion
- }
- /*
- 获取开始节点下一步待选节点:
- 是否属于多次实例化配置(dynamic动态实例化配置:结合办理人动态生成待办节点)
- t:无需检查是否到结束标识,所以按配置的重复实例化策略结合当前操作人生成待办节点,如:生成x级部门办理,下一接口再选具体部门
- f:开始节点配置的下一节点集合
- 获取开始节点所选下一步节点的具体参数:
- 是否属于多次实例化配置
- t:所选x级部门返回对应办理对象集合(具体部门)
- f:按模板配置返回办理对象集合
- 获取待办节点下一步待选节点:
- 是否属于多次实例化配置(无需检查definetion,直接找到当前待办节点获取参数(需要的参数冗余至待办节点上))
- t:检查是否到结束标识(检查当前办理节点的办理对象与结束标识(orglevel:int)是否一致)
- t:返回配置的下一节点(看作单次实例化,当前节点已办完)//definitionId,stepCodes,按配置走
- f:按配置的重复实例化策略结合当前操作人,生成如:{x:X级部门办理},{0:中心办理},最高级最多只能到中心,按动态策略走,动态策略枚举
- 是否处于会签中
- t:按会签策略的下一级 + 上一级(isCSEnd会签汇总节点标记),并对上一级选项打上标记,如:{x:X级部门办理},{0:中心办理},按动态策略走,动态策略枚举
- f:按照definition(按配置走)
- 返回当前节点的配置下一步
- 获取下一步的具体参数:
- 检查模式
- 按动态策略:依据当前操作人、动态类型枚举 查询对应待选部门
- 按配置策略:原有实现方案
- start:
- check配置是否允许当前用户发起
- next: (nextStepCode/x, userId[]/orgId[],dto.other)
- check该不该当前用户办(handlers,all不需要check)
- 办理当前节点
- 创建后面节点
- 是否动态实例化
- t:检查是否到结束标识(参数orgId==mark?)
- t:(参数时stepcode)按配置创建
- f:(参数是x级部门)按动态实例化策略创建
- 是否处于会签中
- t: 是否返回上一级汇总 (isCSEnd)
- t: 1.update上一级的会签完成情况[]
- 2.如果会签全完成,创建新的待办汇总节点(IsCountersignSummaryStep = true)?更新发起节点状态?thk
- f: 创建新的下一步节点
- */
|