Exemple #1
0
        /// <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);
        }
Exemple #2
0
 public FlowOperateing(TEntity entity, FlowOperateInput operateInput, IEnumerable <FlowProcess> flowProcess)
 {
     Entity       = entity;
     FlowProcess  = flowProcess;
     OperateInput = operateInput;
 }
Exemple #3
0
        /// <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
            });
        }
Exemple #4
0
        /// <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 }
            });
        }
Exemple #5
0
        /// <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));
        }
Exemple #6
0
        /// <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 }
                });
            }
        }
Exemple #7
0
        /// <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
                    }),
                },
            });
        }
Exemple #8
0
        /// <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 }
            });
        }
Exemple #9
0
 public FlowOperateBefore(TEntity entity, FlowOperateInput operateInput)
 {
     Entity       = entity;
     OperateInput = operateInput;
 }