/// <summary> /// 根据不同退回场景创建运行时管理器 /// </summary> /// <param name="runningActivityInstanceList">运行节点列表</param> /// <param name="sendbackOperation">退回类型</param> /// <param name="runner">执行者</param> /// <param name="result">结果对象</param> /// <returns>运行时管理器</returns> private static WfRuntimeManager CreateRuntimeInstanceSendbackByCase( List <ActivityInstanceEntity> runningActivityInstanceList, SendbackOperationTypeEnum sendbackOperation, WfAppRunner runner, ref WfExecutedResult result) { WfRuntimeManager rmins = new WfRuntimeManagerSendBack(); rmins.WfExecutedResult = result = new WfExecutedResult(); ActivityInstanceEntity runningNode = runningActivityInstanceList.Where(x => x.ActivityState == (int)ActivityStateEnum.Running).OrderBy(x => x.ID).FirstOrDefault(); if (runningNode == null) { runningNode = runningActivityInstanceList[0]; } ProcessInstanceEntity processInstance = (new ProcessInstanceManager()).GetById(runningNode.ProcessInstanceID); IProcessModel processModel = ProcessModelFactory.Create(processInstance.ProcessGUID, processInstance.Version); var aim = new ActivityInstanceManager(); //以下处理,需要知道上一步是独立节点的信息 //获取上一步流转节点信息,可能经过And, Or等路由节点 var tim = new TransitionInstanceManager(); bool hasGatewayNode = false; var currentNode = runningNode; var lastActivityInstanceList = tim.GetPreviousActivityInstance(currentNode, true, out hasGatewayNode).ToList(); if (lastActivityInstanceList == null || lastActivityInstanceList.Count == 0 || lastActivityInstanceList.Count > 1) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Sendback_NullOrHasTooMany; result.Message = "当前没有可以退回的节点,或者有多个可以退回的节点,无法选择!"; return(rmins); } TransitionInstanceEntity lastTaskTransitionInstance = tim.GetLastTaskTransition(runner.AppName, runner.AppInstanceID, runner.ProcessGUID); if (lastTaskTransitionInstance.TransitionType == (short)TransitionTypeEnum.Loop) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Sendback_IsLoopNode; result.Message = "当前流转是自循环,无需退回!"; return(rmins); } //设置退回节点的相关信息 var previousActivityInstance = lastActivityInstanceList[0]; if (previousActivityInstance.ActivityType == (short)ActivityTypeEnum.StartNode) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Sendback_PreviousIsStartNode; result.Message = "上一步是开始节点,无需退回!"; return(rmins); } if (sendbackOperation == SendbackOperationTypeEnum.Normal) { //简单串行模式下的退回 rmins = new WfRuntimeManagerSendBack(); rmins.WfExecutedResult = result = new WfExecutedResult(); rmins.ProcessModel = processModel; rmins.BackwardContext.ProcessInstance = processInstance; rmins.BackwardContext.BackwardToTaskActivity = processModel.GetActivity(previousActivityInstance.ActivityGUID); rmins.BackwardContext.BackwardToTaskActivityInstance = previousActivityInstance; rmins.BackwardContext.BackwardToTargetTransitionGUID = hasGatewayNode == false ? lastTaskTransitionInstance.TransitionGUID : String.Empty; //如果中间有Gateway节点,则没有直接相连的TransitonGUID rmins.BackwardContext.BackwardFromActivity = processModel.GetActivity(runningNode.ActivityGUID); rmins.BackwardContext.BackwardFromActivityInstance = runningNode; rmins.BackwardContext.BackwardTaskReceiver = WfBackwardTaskReceiver.Instance(previousActivityInstance.ActivityName, previousActivityInstance.EndedByUserID, previousActivityInstance.EndedByUserName); //封装AppUser对象 rmins.AppRunner.AppName = runner.AppName; rmins.AppRunner.AppInstanceID = runner.AppInstanceID; rmins.AppRunner.ProcessGUID = runner.ProcessGUID; rmins.AppRunner.UserID = runner.UserID; rmins.AppRunner.UserName = runner.UserName; rmins.AppRunner.NextActivityPerformers = ActivityResource.CreateNextActivityPerformers(previousActivityInstance.ActivityGUID, previousActivityInstance.EndedByUserID, previousActivityInstance.EndedByUserName); rmins.ActivityResource = new ActivityResource(runner, rmins.AppRunner.NextActivityPerformers); return(rmins); } //如果有其它模式,没有处理到,则直接抛出异常 throw new WorkflowException("未知的退回场景,请报告给技术支持人员!"); }
/// <summary> /// 退回操作 /// </summary> /// <param name="runner">执行者</param> /// <param name="result">结果对象</param> /// <returns>运行时实例对象</returns> internal static WfRuntimeManager CreateRuntimeInstanceSendBack(WfAppRunner runner, ref WfExecutedResult result) { WfRuntimeManager rmins = new WfRuntimeManagerSendBack(); rmins.WfExecutedResult = result = new WfExecutedResult(); var aim = new ActivityInstanceManager(); var runningActivityInstanceList = aim.GetRunningActivityInstanceList(runner.AppInstanceID, runner.ProcessGUID).ToList(); SendbackOperationTypeEnum sendbackOperation = SendbackOperationTypeEnum.Default; //当前没有运行状态的节点存在,流程不存在,或者已经结束或取消 if (runningActivityInstanceList == null || runningActivityInstanceList.Count() == 0) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Sendback_NotInRunning; result.Message = "当前没有运行状态的节点存在,流程不存在,或者已经结束或取消"; return(rmins); } if (runningActivityInstanceList.Count() == 1) //如果只有1个运行节点 { var runningNode = runningActivityInstanceList[0]; var activityType = EnumHelper.ParseEnum <ActivityTypeEnum>(runningNode.ActivityType.ToString()); if (XPDLHelper.IsSimpleComponentNode(activityType) == false) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Sendback_NotTaskNode; result.Message = "当前节点不是任务类型的节点,无法退回上一步节点!"; return(rmins); } if (aim.IsMineTask(runningNode, runner.UserID) == false) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Sendback_NotMineTask; result.Message = "不是登录用户的任务,无法退回!"; return(rmins); } //判断当前节点是否是多实例节点 if (runningNode.MIHostActivityInstanceID != null) { if (runningNode.CompleteOrder == 1) { //只有串行模式下有CompleteOrder的值为 1 //串行模式多实例的第一个执行节点,此时可退回到上一步 sendbackOperation = SendbackOperationTypeEnum.MISFirstOneIsRunning; } else if (runningNode.CompleteOrder > 1) { //已经是中间节点,只能退回到上一步多实例子节点 sendbackOperation = SendbackOperationTypeEnum.MISOneIsRunning; } else if (runningNode.CompleteOrder == -1) { sendbackOperation = SendbackOperationTypeEnum.MIPOneIsRunning; } } else { sendbackOperation = SendbackOperationTypeEnum.Normal; } } else if (runningActivityInstanceList.Count() > 1) { var firstActivityInstance = runningActivityInstanceList[0]; if (firstActivityInstance.MIHostActivityInstanceID != null) { //判断多实例主节点下的子节点是否都处于待办状态,如果是,则可以退回到上一步 bool isAllInReadyState = true; var allChildNodeList = aim.GetActivityMultipleInstance(firstActivityInstance.MIHostActivityInstanceID.Value, firstActivityInstance.ProcessInstanceID); int runningCount = 0; foreach (var ai in allChildNodeList) { if (ai.ActivityState != (short)ActivityStateEnum.Ready && ai.ActivityState != (short)ActivityStateEnum.Suspended) { if (ai.ActivityState == (short)ActivityStateEnum.Running) { runningCount++; } else { isAllInReadyState = false; break; } } } if (runningCount > 1) { isAllInReadyState = false; } if (isAllInReadyState == false) { //部分子节点有完成的 sendbackOperation = SendbackOperationTypeEnum.MIPSeveralIsRunning; } else if (runningCount == 1) { if (firstActivityInstance.CompleteOrder == -1) { sendbackOperation = SendbackOperationTypeEnum.MIPOneIsRunning; } else { //第一个子节点处于待办状态 sendbackOperation = SendbackOperationTypeEnum.MISFirstOneIsRunning; } } else if (isAllInReadyState) { //子节点全部处于待办状态 sendbackOperation = SendbackOperationTypeEnum.MIPAllIsInReadyState; } } else { //有其它非多实例的并行节点,暂时不处理,后期实现该功能 result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Sendback_NullOrHasTooMany; result.Message = "有多个可以退回的节点,而且不是多实例节点,此功能暂时不支持!"; return(rmins); } } //根据不同分支场景,创建不同撤销运行时管理器 return(CreateRuntimeInstanceSendbackByCase(runningActivityInstanceList, sendbackOperation, runner, ref result)); }