using Hotline.FlowEngine.Definitions; using Hotline.Share.Enums.FlowEngine; using SqlSugar; using XF.Domain.Entities; using XF.Domain.Repository; namespace Hotline.FlowEngine.Workflows; public class Workflow : CreationEntity { public string DefinitionId { get; set; } [SugarColumn(IsNullable = true)] public string? ModuleId { get; set; } /// /// 业务模块名称 /// [SugarColumn(IsNullable = true)] public string? ModuleName { get; set; } [SugarColumn(IsNullable = true)] public string? ModuleCode { get; set; } [SugarColumn(Length = 2000)] public string Title { get; set; } /// /// 到期时间 /// public DateTime ExpiredTime { get; set; } /// /// 流程流转到end节点的时间(配置模板的end节点前一个节点办理完成时间) /// public DateTime? CompleteTime { get; set; } public EWorkflowStatus Status { get; set; } /// /// 当前办理节点名称(会签状态此字段保存最外层会签办理节点名称) /// [SugarColumn(IsNullable = true)] public string? CurrentStepName { get; set; } /// /// 到达当前办理节点时间(stepBox创建时间) /// public DateTime? CurrentStepTime { get; set; } /// /// 会签办理节点code,嵌套会签为最外层会签办理节点code(不处于会签状态则无值) /// [SugarColumn(IsNullable = true)] public string? TopCountersignStepCode { get; set; } /// /// 中心直办件 /// public bool IsStraight { get; set; } = true; /// /// 交办时间 /// public DateTime AssignTime { get; set; } /// /// 办理时间限制(如:24小时、7个工作日) /// public string TimeLimit { get; set; } /// /// 办理意见(冗余,办理中...or 最终办理意见) /// [SugarColumn(Length = 2000)] public string Opinion { get; set; } = "办理中..."; /// /// 办理人id /// [SugarColumn(ColumnDataType = "varchar(1000)", IsJson = true)] public List HandlerUsers { get; set; } = new(); /// /// 办理部门code /// [SugarColumn(ColumnDataType = "varchar(1000)", IsJson = true)] public List HandlerOrgs { get; set; } = new(); ///// ///// 外部业务唯一标识 ///// //public string ExternalId { get; set; } [Navigate(NavigateType.OneToOne, nameof(DefinitionId))] public Definition Definition { get; set; } /// /// 补充信息 /// [Navigate(NavigateType.OneToMany, nameof(WorkflowSupplement.WorkflowId))] public List Supplements { get; set; } /// /// 接办信息 /// [Navigate(NavigateType.OneToMany, nameof(WorkflowAssign.WorkflowId))] public List Assigns { get; set; } /// /// 会签 /// [Navigate(NavigateType.OneToMany, nameof(WorkflowCountersign.WorkflowId))] public List Countersigns { get; set; } /// /// 主节点,依据流转进度动态生成或删除 /// [SugarColumn(IsIgnore = true)] public List StepBoxes { get; set; } [SugarColumn(IsIgnore = true)] public List Traces { get; set; } = new(); #region Mehod /// /// 流程结束 /// public void Complete() { Status = EWorkflowStatus.Completed; CompleteTime = DateTime.Now; } public void Terminate() { Status = EWorkflowStatus.Terminated; CompleteTime = DateTime.Now; } /// /// 流程进行流转 /// public void FLow(string currentStepName, DateTime currentStepTime, string? currentCountersignCode = null) { CurrentStepName = currentStepName; CurrentStepTime = currentStepTime; if (!string.IsNullOrEmpty(currentCountersignCode)) TopCountersignStepCode = currentCountersignCode; } /// /// 检查会签是否结束 /// public bool CheckIfCountersignOver() { //var countersignStepBox = StepBoxes.First(d => d.Code == TopCountersignStepCode); //var isCountersignOver = countersignStepBox.Steps.All(d => // d.Status is EWorkflowStepStatus.Completed && // (!d.HasStartCountersign || d.IsCountersignComplete.GetValueOrDefault())); //return isCountersignOver; return Countersigns.All(d => d.IsCompleted()); } public void EndCountersign() => TopCountersignStepCode = null; /// /// 更新workflow中当前停留节点,时间和会签开始节点code /// /// /// public void SetWorkflowCurrentStepInfo(bool isStartCountersign, WorkflowStep stepBox) { //1.不在会签中,未发起会签(普通处理) 2.不在会签中,发起会签(保存会签节点),3.会签中,不更新 if (IsInCountersign()) return; if (isStartCountersign) { FLow(stepBox.Name, stepBox.CreationTime, stepBox.Code); } else { FLow(stepBox.Name, stepBox.CreationTime); } } /// /// 流程是否处于会签中 /// /// public bool IsInCountersign() => !string.IsNullOrEmpty(TopCountersignStepCode); /// /// 结束流程会签状态 /// public void CloseCountersignStatus() => TopCountersignStepCode = null; /// /// 重置最终办理意见 /// public void ResetOption() => Opinion = "办理中..."; /// /// 更新当前办理人(代办人或部门) /// public void UpdateHandlers(string handlerId, string handlerOrg, EFlowAssignType assignType, IEnumerable handlers) { HandlerUsers.Remove(handlerId); HandlerOrgs.Remove(handlerOrg); switch (assignType) { case EFlowAssignType.Org: HandlerOrgs.AddRange(handlers); HandlerOrgs = HandlerOrgs.Distinct().ToList(); break; case EFlowAssignType.User: HandlerUsers.AddRange(handlers); HandlerUsers = HandlerUsers.Distinct().ToList(); break; default: throw new ArgumentOutOfRangeException(nameof(assignType), assignType, null); } } /// /// 当前用户是否可以办理该流程 /// /// public bool CanHandle(string userId, string orgCode) => HandlerUsers.Contains(userId) || HandlerOrgs.Contains(orgCode); #endregion }