/// <summary> /// 流程操作 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entity"></param> /// <param name="flowOperate"></param> /// <returns></returns> public async Task <FlowOperateOutput> HandleFlowOperateAsync <TEntity>(TEntity entity, FlowOperateInput flowOperate) where TEntity : class, IHaveCheck { if (entity is null) { throw new ArgumentNullException(nameof(entity)); } if (flowOperate is null) { throw new ArgumentNullException(nameof(flowOperate)); } var eventBus = serviceProvider.GetService <IEventBus>(); var unitOfWork = serviceProvider.GetService <IUnitOfWork>(); await eventBus.TriggerEventAsync(new FlowOperateBefore <TEntity>(entity, flowOperate)); FlowOperateOutput handleResult = flowOperate.ActionEnum switch { FlowActionEnum.submit => await HandleSubmitActionAsync(entity, flowOperate), FlowActionEnum.unsubmit => await HandleUnSubmitActionAsync(entity, flowOperate), FlowActionEnum.pass => await HandlePassActionAsync(entity, flowOperate), FlowActionEnum.withdraw => await HandleWithdrawActionAsync(entity, flowOperate), FlowActionEnum.refuse => await HandleRefuseActionAsync(entity, flowOperate), FlowActionEnum.uncheck => await HandleUnCheckActionAsync(entity, flowOperate), _ => throw new NotImplementedException(), }; entity.FlowStatus = handleResult.FlowStatus; var entityRepisitory = LoadRepository <TEntity>(); await entityRepisitory.UpdateAsync(entity); await eventBus.TriggerEventAsync(new FlowOperateing <TEntity>(entity, flowOperate, handleResult.FlowProcesses)); await unitOfWork.CommmitAsync(); await eventBus.TriggerEventAsync(new FlowOperated <TEntity>(entity, flowOperate, handleResult.FlowProcesses)); return(handleResult); }
public FlowOperateing(TEntity entity, FlowOperateInput operateInput, IEnumerable <FlowProcess> flowProcess) { Entity = entity; FlowProcess = flowProcess; OperateInput = operateInput; }
/// <summary> /// 处理撤回动作 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entity"></param> /// <param name="flowOperate"></param> /// <returns></returns> public async Task <FlowOperateOutput> HandleUnSubmitActionAsync <TEntity>(TEntity entity, FlowOperateInput flowOperate) where TEntity : class, IHaveCheck { var flowInstances = LoadRepository <FlowInstance>(); var flowProcesses = LoadRepository <FlowProcess>(); var flowSteps = LoadRepository <FlowStep>(); var currUser = AppSession.CurrUser; var flowInstance = await flowInstances .Where(v => v.Bill_Id == entity.Id && v.Enabled == EnabledMark.enabled) .OrderByDescending(v => v.Version) .FirstOrDefaultAsync(); if (flowInstance == null) { throw new MsgException("流程未提交"); } //if (entity.FlowStatus != FlowStatusEnum.processing) // throw new MsgException("流程已完结,不可撤回!"); flowInstance.IsComlete = true; flowInstance.CompleteTime = DateTime.Now; flowInstance.CurrStep_Id = null; flowInstance.Enabled = EnabledMark.disabled; flowInstance.Status = FlowStatusEnum.unsubmitted; await flowInstances.UpdateAsync(flowInstance); var lastStep = await flowSteps .Where(v => v.FlowInstance_Id == flowInstance.Id && v.FlowNodeKey == -1) .Select(v => new { v.Id, v.StepName }) .FirstOrDefaultAsync(); var flowProcess = await flowProcesses.AddAsync(new FlowProcess { Action = FlowActionEnum.unsubmit, Desc = flowOperate.Desc, FlowInstance_Id = flowInstance.Id, FlowStep_Id = lastStep.Id, FlowStepName = lastStep.StepName, Id = null, OperaterName = currUser.Name, Operater_Id = currUser.Id, OperateTime = DateTime.Now, NodeKey = -1 }); return(new FlowOperateOutput { FlowProcesses = new[] { flowProcess }, FlowStatus = FlowStatusEnum.unsubmitted }); }
/// <summary> /// 处理提交动作 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entity"></param> /// <param name="flowOperate"></param> /// <returns></returns> public async Task <FlowOperateOutput> HandleSubmitActionAsync <TEntity>(TEntity entity, FlowOperateInput flowOperate) where TEntity : class, IHaveCheck { var currUser = AppSession.CurrUser; var flowInstances = LoadRepository <FlowInstance>(); var flowProcesses = LoadRepository <FlowProcess>(); var flowInstanceDepts = LoadRepository <FlowInstanceDept>(); var flowSteps = LoadRepository <FlowStep>(); var flowStepUsers = LoadRepository <FlowStepUser>(); var flowSnapshots = LoadRepository <FlowSnapshot>(); var deptMembers = LoadRepository <DeptMember>(); var workFlows = LoadRepository <WorkFlow>(); var eventBuses = serviceProvider.GetService <IEventBus>(); /*1,判断之前是否有提交过,有则判断是否结束*/ var beforeInstance = await flowInstances .Where(v => v.Bill_Id == entity.Id) .OrderByDescending(v => v.Version) .Select(v => new { v.Version, v.Enabled }) .FirstOrDefaultAsync(); if (entity.FlowStatus != FlowStatusEnum.unsubmitted || entity.FlowStatus != FlowStatusEnum.returned) { throw new MsgException("只有未提交/已退回的单据,才可重新提交!"); } if (beforeInstance != null && beforeInstance.Enabled == EnabledMark.enabled) { throw new MsgException("流程还没结束,不可重新提交!"); } var type = typeof(TEntity); var beModuleText = serviceProvider.GetService <IModuleDesProvider>().GetClassDescription(type); /*2,取模块对应的流程ID*/ var flowId = await workFlows .Where(v => v.BeModule == type.Name && v.Enabled == EnabledMark.enabled) .OrderByDescending(v => v.Version) .Select(v => v.Id) .FirstOrDefaultAsync(); if (flowId.IsNullOrWhiteSpace()) { throw new MsgException("未配置流程"); } /*3,创建一个新的流程实例*/ var flowInstance = new FlowInstance { BillNumber = null, BeModuleName = type.Name, BeModuleText = beModuleText, Bill_Id = entity.Id, Id = null, CompleteTime = null, CurrStep_Id = null, IsComlete = false, LastChecker_Id = null, LastCheckTime = null, Sponsor_Id = currUser?.Id, StartTime = DateTime.Now, Status = FlowStatusEnum.submitted, WorkFlow_Id = flowId, Enabled = EnabledMark.enabled, Version = beforeInstance?.Version ?? 0 + 1 }; if (entity is IHaveNumber numberEntity) { flowInstance.BillNumber = numberEntity.Number; } /*单据有部门,则取单据上的部门*/ if (entity is IHaveDept haveDept) { foreach (var deptId in haveDept.GetBeDeptIds()) { await flowInstanceDepts.AddAsync(new FlowInstanceDept { BeDept_Id = deptId, FlowInstance_Id = flowInstance.Id }); } } /*否则则取提交人的部门*/ else { var deptIds = await deptMembers .Where(r => r.IsManager && deptMembers.Any(v => v.User_Id == currUser.Id && v.Dept_Id == r.Dept_Id)) .Select(v => v.Dept_Id) .Distinct() .ToListAsync(); foreach (var deptId in deptIds) { await flowInstanceDepts.AddAsync(new FlowInstanceDept { BeDept_Id = deptId, FlowInstance_Id = flowInstance.Id }); } } await flowInstances.AddAsync(flowInstance); /*4,取出流程配置并保存快照*/ var workFlowDto = await eventBuses.RequestAsync <WorkFlowDto, string>(flowId); await flowSnapshots.AddAsync(new FlowSnapshot { FlowInstance_Id = flowInstance.Id, FKey_Id = flowId, SnapshotContent = workFlowDto.ToJson() }); /*5,缓存单据快照*/ await flowSnapshots.AddAsync(new FlowSnapshot { FlowInstance_Id = flowInstance.Id, FKey_Id = entity.Id, SnapshotContent = entity.ToJson() }); /*6,计算步骤与审核人*/ var flowNodes = workFlowDto.Nodes; var flowLines = workFlowDto.Lines; List <FlowNodeDto> stepNodes = GenerateFlowSteps(entity, flowNodes, flowLines); /*7, 插入流程步骤*/ var stepList = new List <FlowStep>(); for (int i = 0; i < stepNodes.Count; i++) { var stepNode = stepNodes[i]; var flowStep = await flowSteps.AddAsync(new FlowStep { FlowInstance_Id = flowInstance.Id, FlowNode_Id = stepNode.Id, PrevStep_Id = null, NextStep_Id = null, StepOrder = i + 1, StepName = stepNode.Name, FlowNodeKey = stepNode.Key, PrevStepKey = 0, NextStepKey = -1 }); stepList.Add(flowStep); /*匹配可审核的人(起点和终点不需要)*/ if (stepNode.Key == 0 || stepNode.Key == -1) { continue; } var stepUserList = await MatchStepCheckUser(entity, stepNode); foreach (var stepUser in stepUserList) { stepUser.FlowInstance_Id = flowInstance.Id; stepUser.FlowStep_Id = flowStep.Id; await flowStepUsers.AddAsync(stepUser); } } for (int i = 1; i < stepList.Count - 1; i++) { var currStep = stepList[i]; var prevStep = stepList[i - 1]; var nextStep = stepList[i + 1]; currStep.PrevStep_Id = prevStep.Id; currStep.PrevStepKey = prevStep.FlowNodeKey; currStep.NextStep_Id = nextStep.Id; currStep.NextStepKey = nextStep.FlowNodeKey; } /*8,插入审核过程*/ var startStep = stepList[0]; var flowProcess = await flowProcesses.AddAsync(new FlowProcess { Id = null, FlowStep_Id = startStep.Id, Action = FlowActionEnum.submit, Desc = flowOperate.Desc, FlowInstance_Id = flowInstance.Id, FlowStepName = startStep.StepName, OperateTime = DateTime.Now, Operater_Id = currUser.Id, OperaterName = currUser.Name, NodeKey = 0 }); flowInstance.CurrStep_Id = stepList[1].Id; return(new FlowOperateOutput { FlowStatus = FlowStatusEnum.submitted, FlowProcesses = new[] { flowProcess } }); }
/// <summary> /// 流程操作 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="id"></param> /// <param name="flowOperate"></param> /// <returns></returns> public async Task <FlowOperateOutput> HandleFlowOperateAsync <TEntity>(string id, FlowOperateInput flowOperate) where TEntity : class, IHaveCheck { var entityRepisitory = LoadRepository <TEntity>(); var entity = await entityRepisitory.GetAsync(id); if (entity == null) { throw new NotFoundException(); } return(await HandleFlowOperateAsync(entity, flowOperate)); }
/// <summary> /// 处理审核通过动作 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entity"></param> /// <param name="flowOperate"></param> /// <returns></returns> public async Task <FlowOperateOutput> HandlePassActionAsync <TEntity>(TEntity entity, FlowOperateInput flowOperate) where TEntity : class, IHaveCheck { var flowInstances = LoadRepository <FlowInstance>(); var flowProcesses = LoadRepository <FlowProcess>(); var flowSteps = LoadRepository <FlowStep>(); var currUser = AppSession.CurrUser; var flowOperateOutput = new FlowOperateOutput(); var flowInstance = await flowInstances .Where(v => v.Bill_Id == entity.Id && v.Enabled == EnabledMark.enabled) .OrderByDescending(v => v.Version) .FirstOrDefaultAsync(); if (flowInstance == null) { throw new MsgException("流程未提交"); } if (!await VerificationCanCheck(entity.Id)) { throw new MsgException("你没有权限处理当前步骤!"); } var currStep = await flowSteps .Where(v => v.Id == flowInstance.CurrStep_Id) .Select(v => new { v.FlowNodeKey, v.NextStepKey, v.NextStep_Id, v.StepName, v.Id }) .FirstOrDefaultAsync(); if (currStep == null) { throw new MsgException("获取审批步骤失败!"); } var flowProcess = await flowProcesses.AddAsync(new FlowProcess { Action = FlowActionEnum.pass, Desc = flowOperate.Desc, FlowInstance_Id = flowInstance.Id, FlowStep_Id = currStep.Id, FlowStepName = currStep.StepName, Id = null, OperaterName = currUser.Name, Operater_Id = currUser.Id, OperateTime = DateTime.Now, NodeKey = currStep.FlowNodeKey }); flowInstance.LastChecker_Id = currUser.Id; flowInstance.LastCheckTime = DateTime.Now; /*当到达最后一步时*/ if (currStep.NextStepKey == -1) { flowInstance.CurrStep_Id = null; flowInstance.CompleteTime = DateTime.Now; flowInstance.IsComlete = true; flowInstance.Status = FlowStatusEnum.finished; await flowInstances.UpdateAsync(flowInstance); var nextStep = await flowSteps .Where(v => v.Id == currStep.NextStep_Id) .Select(v => new { v.StepName, v.Id }) .FirstOrDefaultAsync(); var lastFlowProcess = await flowProcesses.AddAsync(new FlowProcess { Action = FlowActionEnum.pass, Desc = "审批完结", FlowInstance_Id = flowInstance.Id, FlowStep_Id = nextStep.Id, FlowStepName = nextStep.StepName, Id = null, OperaterName = currUser.Name, Operater_Id = currUser.Id, OperateTime = DateTime.Now, NodeKey = currStep.FlowNodeKey }); return(new FlowOperateOutput { FlowStatus = FlowStatusEnum.returned, FlowProcesses = new[] { flowProcess, lastFlowProcess } }); } else { flowInstance.CurrStep_Id = currStep.NextStep_Id; await flowInstances.UpdateAsync(flowInstance); return(new FlowOperateOutput { FlowStatus = FlowStatusEnum.processing, FlowProcesses = new[] { flowProcess } }); } }
/// <summary> /// 处理退回动作 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entity"></param> /// <param name="flowOperate"></param> /// <returns></returns> public async Task <FlowOperateOutput> HandleWithdrawActionAsync <TEntity>(TEntity entity, FlowOperateInput flowOperate) where TEntity : class, IHaveCheck { var flowInstances = LoadRepository <FlowInstance>(); var flowProcesses = LoadRepository <FlowProcess>(); var flowSteps = LoadRepository <FlowStep>(); var currUser = AppSession.CurrUser; var flowInstance = await flowInstances .Where(v => v.Bill_Id == entity.Id && v.Enabled == EnabledMark.enabled) .OrderByDescending(v => v.Version) .FirstOrDefaultAsync(); if (flowInstance == null) { throw new MsgException("流程未提交"); } if (!await VerificationCanCheck(entity.Id)) { throw new MsgException("你没有权限处理当前步骤!"); } flowInstance.IsComlete = true; flowInstance.CompleteTime = DateTime.Now; flowInstance.CurrStep_Id = null; flowInstance.Enabled = EnabledMark.disabled; flowInstance.Status = FlowStatusEnum.returned; await flowInstances.UpdateAsync(flowInstance); var currStep = await flowSteps .Where(v => v.Id == flowInstance.CurrStep_Id) .Select(v => new { v.Id, v.StepName, v.FlowNodeKey }) .FirstOrDefaultAsync(); var lastStep = await flowSteps .Where(v => v.FlowInstance_Id == flowInstance.Id && v.FlowNodeKey == -1) .Select(v => new { v.Id, v.StepName, v.FlowNodeKey }) .FirstOrDefaultAsync(); return(new FlowOperateOutput { FlowStatus = flowInstance.Status, FlowProcesses = new[] { await flowProcesses.AddAsync(new FlowProcess { Action = flowOperate.ActionEnum, Desc = flowOperate.Desc, FlowInstance_Id = flowInstance.Id, FlowStep_Id = currStep.Id, FlowStepName = currStep.StepName, Id = null, OperaterName = currUser.Name, Operater_Id = currUser.Id, OperateTime = DateTime.Now, NodeKey = currStep.FlowNodeKey }), await flowProcesses.AddAsync(new FlowProcess { Action = flowOperate.ActionEnum, Desc = "已完结", FlowInstance_Id = flowInstance.Id, FlowStep_Id = lastStep.Id, FlowStepName = lastStep.StepName, Id = null, OperaterName = currUser.Name, Operater_Id = currUser.Id, OperateTime = DateTime.Now, NodeKey = lastStep.FlowNodeKey }), }, }); }
/// <summary> /// 处理反审核操作 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entity"></param> /// <param name="flowOperate"></param> /// <returns></returns> public async Task <FlowOperateOutput> HandleUnCheckActionAsync <TEntity>(TEntity entity, FlowOperateInput flowOperate) where TEntity : class, IHaveCheck { var flowInstances = LoadRepository <FlowInstance>(); var flowProcesses = LoadRepository <FlowProcess>(); var flowSteps = LoadRepository <FlowStep>(); var currUser = AppSession.CurrUser; var flowInstance = await flowInstances .Where(v => v.Bill_Id == entity.Id) .OrderByDescending(v => v.Version) .FirstOrDefaultAsync(); if (flowInstance == null) { throw new MsgException("流程未提交"); } /*最后一次操作*/ var lastProcess = await flowProcesses .Where(v => v.FlowInstance_Id == flowInstance.Id && v.NodeKey != -1 && v.NodeKey != 0) .OrderByDescending(v => v.Id) .FirstOrDefaultAsync(); if (lastProcess == null || lastProcess.Operater_Id != currUser.Id) { throw new MsgException("只能反审核流程的最后一步,当前流程的最后一步不是由您审核的"); } flowInstance.Enabled = EnabledMark.enabled; flowInstance.Status = FlowStatusEnum.processing; flowInstance.IsComlete = false; flowInstance.LastCheckTime = DateTime.Now; flowInstance.LastChecker_Id = currUser.Id; flowInstance.CompleteTime = null; flowInstance.CurrStep_Id = lastProcess.FlowStep_Id; await flowInstances.UpdateAsync(flowInstance); var flowProcess = await flowProcesses.AddAsync(new FlowProcess { Action = flowOperate.ActionEnum, Desc = flowOperate.Desc, FlowInstance_Id = flowInstance.Id, FlowStepName = lastProcess.FlowStepName, Id = null, FlowStep_Id = lastProcess.FlowStep_Id, NodeKey = lastProcess.NodeKey, OperaterName = currUser.Name, Operater_Id = currUser.Id, OperateTime = DateTime.Now }); return(new FlowOperateOutput { FlowStatus = flowInstance.Status, FlowProcesses = new[] { flowProcess } }); }
public FlowOperateBefore(TEntity entity, FlowOperateInput operateInput) { Entity = entity; OperateInput = operateInput; }