/// <summary> /// 撤销操作 /// 包括: /// 1) 正常流转 /// 2) 多实例节点流转 /// </summary> /// <param name="runner">执行者</param> /// <param name="result">结果对象</param> /// <returns>运行时实例对象</returns> internal static WfRuntimeManager CreateRuntimeInstanceWithdraw(WfAppRunner runner, ref WfExecutedResult result) { WfRuntimeManager rmins = new WfRuntimeManagerWithdraw(); rmins.WfExecutedResult = result = new WfExecutedResult(); var aim = new ActivityInstanceManager(); var runningActivityInstanceList = aim.GetRunningActivityInstanceList(runner.AppInstanceID, runner.ProcessGUID).ToList(); WithdrawOperationTypeEnum withdrawOperation = WithdrawOperationTypeEnum.Default; //当前没有运行状态的节点存在,流程不存在,或者已经结束或取消 if (runningActivityInstanceList == null || runningActivityInstanceList.Count() == 0) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_NotInReady; result.Message = "当前没有运行状态的节点存在,流程不存在,或者已经结束或取消"; return(rmins); } if (runningActivityInstanceList.Count() == 1) //如果只有1个运行节点 { //先判断节点的状态是否是有效状态 var runningNode = runningActivityInstanceList[0]; if (runningNode.ActivityState != (short)ActivityStateEnum.Ready && runningNode.ActivityState != (short)ActivityStateEnum.Suspended) //只有准备或挂起状态的节点可以撤销 { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_NotInReady; result.Message = string.Format("无法撤销到上一步,因为要撤销的节点为空,或不在【待办/挂起】状态,当前状态: {0}", runningNode.ActivityState);//,节点状态:{0} runningNode.ActivityState 为空报错20150514 return(rmins); } //当前运行节点是普通节点模式 withdrawOperation = WithdrawOperationTypeEnum.Normal; } //根据不同分支场景,创建不同撤销运行时管理器 return(CreateRuntimeInstanceWithdrawByCase(runningActivityInstanceList, withdrawOperation, runner, ref result)); }
/// <summary> /// 根据不同撤销场景创建运行时管理器 /// </summary> /// <param name="runningActivityInstanceList">运行节点列表</param> /// <param name="withdrawOperation">撤销类型</param> /// <param name="runner">执行者</param> /// <param name="result">结果对象</param> /// <returns>运行时管理器</returns> private static WfRuntimeManager CreateRuntimeInstanceWithdrawByCase( List <ActivityInstanceEntity> runningActivityInstanceList, WithdrawOperationTypeEnum withdrawOperation, WfAppRunner runner, ref WfExecutedResult result) { WfRuntimeManager rmins = new WfRuntimeManagerWithdraw(); rmins.WfExecutedResult = result = new WfExecutedResult(); //根据当前运行节点获取 ActivityInstanceEntity 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; if (runningNode.MIHostActivityInstanceID != null) { //如果当前运行节点是多实例子节点,则需要找到它的主节点的Transiton记录 currentNode = aim.GetById(runningNode.MIHostActivityInstanceID.Value); } var lastActivityInstanceList = tim.GetPreviousActivityInstanceList(currentNode, false, out hasGatewayNode).ToList(); if (lastActivityInstanceList == null || lastActivityInstanceList.Count > 1) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_HasTooMany; result.Message = "当前没有可以撤销回去的节点,或者有多个可以撤销回去的节点,无法选择!"; return(rmins); } TransitionInstanceEntity lastTaskTransitionInstance = null; if (hasGatewayNode == false) { lastTaskTransitionInstance = tim.GetLastTaskTransition(runner.AppName, runner.AppInstanceID, runner.ProcessGUID); if (lastTaskTransitionInstance.TransitionType == (short)TransitionTypeEnum.Loop) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_IsLoopNode; result.Message = "当前流转是自循环,无需撤销!"; return(rmins); } } var previousActivityInstance = lastActivityInstanceList[0]; if (previousActivityInstance.EndedByUserID != runner.UserID) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_NotCreatedByMine; result.Message = string.Format("上一步节点的任务办理人跟当前登录用户不一致,无法撤销回上一步!节点办理人:{0}", previousActivityInstance.EndedByUserName); return(rmins); } if (previousActivityInstance.ActivityType == (short)ActivityTypeEnum.EndNode) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_PreviousIsEndNode; result.Message = "上一步是结束节点,无法撤销!"; return(rmins); } //当前运行节点是普通节点 if (withdrawOperation == WithdrawOperationTypeEnum.Normal) { //简单串行模式下的退回 rmins = new WfRuntimeManagerWithdraw(); rmins.WfExecutedResult = result = new WfExecutedResult(); rmins.ProcessModel = processModel; rmins.AppRunner.ProcessGUID = runner.ProcessGUID; rmins.BackwardContext.ProcessInstance = processInstance; rmins.BackwardContext.BackwardToTargetTransitionGUID = hasGatewayNode == false ? lastTaskTransitionInstance.TransitionGUID : String.Empty; rmins.BackwardContext.BackwardToTaskActivity = processModel.GetActivity(previousActivityInstance.ActivityGUID); rmins.BackwardContext.BackwardToTaskActivityInstance = previousActivityInstance; 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.UserID = runner.UserID; rmins.AppRunner.UserName = runner.UserName; rmins.AppRunner.NextActivityPerformers = ActivityResource.CreateNextActivityPerformers( previousActivityInstance.ActivityGUID, runner.UserID, runner.UserName); rmins.ActivityResource = new ActivityResource(runner, rmins.AppRunner.NextActivityPerformers); return(rmins); } //如果有其它模式,没有处理到,则直接抛出异常 throw new WorkflowException("未知的撤销场景,请报告给技术支持人员!"); }
/// <summary> /// 撤销操作 /// 包括: /// 1) 正常流转 /// 2) 多实例节点流转 /// </summary> /// <param name="runner">执行者</param> /// <param name="result">结果对象</param> /// <returns>运行时实例对象</returns> internal static WfRuntimeManager CreateRuntimeInstanceWithdraw(WfAppRunner runner, ref WfExecutedResult result) { WfRuntimeManager rmins = new WfRuntimeManagerWithdraw(); rmins.WfExecutedResult = result = new WfExecutedResult(); var aim = new ActivityInstanceManager(); var runningActivityInstanceList = aim.GetRunningActivityInstanceList(runner.AppInstanceID, runner.ProcessGUID).ToList(); WithdrawOperationTypeEnum withdrawOperation = WithdrawOperationTypeEnum.Default; //当前没有运行状态的节点存在,流程不存在,或者已经结束或取消 if (runningActivityInstanceList == null || runningActivityInstanceList.Count() == 0) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_NotInReady; result.Message = "当前没有运行状态的节点存在,流程不存在,或者已经结束或取消"; return(rmins); } if (runningActivityInstanceList.Count() == 1) //如果只有1个运行节点 { //先判断节点的状态是否是有效状态 var runningNode = runningActivityInstanceList[0]; if (runningNode.ActivityState != (short)ActivityStateEnum.Ready && runningNode.ActivityState != (short)ActivityStateEnum.Suspended) //只有准备或挂起状态的节点可以撤销 { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_NotInReady; result.Message = string.Format("无法撤销到上一步,因为要撤销的节点为空,或不在【待办/挂起】状态,当前状态: {0}", runningNode.ActivityState);//,节点状态:{0} runningNode.ActivityState 为空报错20150514 return(rmins); } //判断是否是多实例节点的子节点 if (runningNode.MIHostActivityInstanceID != null) { if (runningNode.CompleteOrder == 1) { //只有串行模式下有CompleteOrder的值为 1 //串行模式多实例的第一个执行节点,此时上一步骤可以撤销 withdrawOperation = WithdrawOperationTypeEnum.MISFirstOneIsRunning; } else if (runningNode.CompleteOrder > 1) { //串行模式多实例内部撤销,其中只有1个节点处于运行状态 withdrawOperation = WithdrawOperationTypeEnum.MISOneIsRunning; } else if (runningNode.CompleteOrder == -1) { //并行模式下CompleteOrder的值为 -1,此时只剩余最后一个 //要撤销的话,是对并行会签节点的内部撤销,即认为是重新办理,找到当前运行人的节点,置状态为待办状态就可以 withdrawOperation = WithdrawOperationTypeEnum.MIPSeveralIsRunning; } } else { //当前运行节点是普通节点模式 withdrawOperation = WithdrawOperationTypeEnum.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); foreach (var ai in allChildNodeList) { if (ai.ActivityState != (short)ActivityStateEnum.Ready && ai.ActivityState != (short)ActivityStateEnum.Suspended) { isAllInReadyState = false; break; } } if (isAllInReadyState == true) { //子节点全部处于待办状态 withdrawOperation = WithdrawOperationTypeEnum.MIPAllIsInReadyState; } else { //部分子节点有完成的 withdrawOperation = WithdrawOperationTypeEnum.MIPSeveralIsRunning; } } else { //有其它非多实例的并行节点,暂时不处理,后期实现该功能 result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_HasTooMany; result.Message = "有多个可以撤销回去的节点,而且不是多实例节点,此功能暂时不支持!"; return(rmins); } } //根据不同分支场景,创建不同撤销运行时管理器 return(CreateRuntimeInstanceWithdrawByCase(runningActivityInstanceList, withdrawOperation, runner, ref result)); }