/// <summary> /// 撤销操作 /// 包括: /// 1) 正常流转 /// 2) 多实例节点流转 /// </summary> /// <param name="appName"></param> /// <param name="appInstanceID"></param> /// <param name="processGUID"></param> /// <param name="userID"></param> /// <param name="userName"></param> /// <param name="result"></param> /// <returns></returns> public static WfRuntimeManager CreateRuntimeInstanceWithdraw(WfAppRunner runner, ref WfExecutedResult result) { WfRuntimeManager rmins = null; //获取当前运行节点信息 var aim = new ActivityInstanceManager(); var runningNode = aim.GetRunningNode(runner); var processInstance = (new ProcessInstanceManager()).GetById(runningNode.ProcessInstanceID); var processModel = (new ProcessModel(processInstance.ProcessGUID, processInstance.Version)); if ((runningNode == null) || (runningNode.ActivityState != (short)ActivityStateEnum.Ready)) { 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 && runningNode.MIHostActivityInstanceID.Value > 0) { //获取同一会签主节点下的前置节点信息 var previousActivityInstance = aim.GetPreviousOfMultipleInstanceNode( runningNode.MIHostActivityInstanceID.Value, runningNode.ID, runningNode.CompleteOrder.Value); if (previousActivityInstance != null && previousActivityInstance.EndedByUserID == runner.UserID) { //返回多实例节点下的处理模式 rmins = new WfRuntimeManagerWithdrawMI(); rmins.WfExecutedResult = result = new WfExecutedResult(); rmins.BackwardContext.ProcessInstance = processInstance; rmins.BackwardContext.BackwardToTaskActivity = processModel.GetActivity(previousActivityInstance.ActivityGUID); rmins.BackwardContext.BackwardToTaskActivityInstance = previousActivityInstance; rmins.BackwardContext.BackwardFromActivityInstance = runningNode; //准备状态的接收节点 rmins.BackwardContext.BackwardTaskReciever = WfBackwardTaskReciever.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); } } //以下部分是处理非多实例节点的情况 //正常流转过程,无会签加签等特殊场景 rmins = new WfRuntimeManagerWithdraw(); rmins.WfExecutedResult = result = new WfExecutedResult(); //获取上一步流转节点信息,可能经过And, Or等路由节点 var tim = new TransitionInstanceManager(); bool hasGatewayNode = false; var lastActivityInstanceList = tim.GetPreviousActivityInstance(runningNode, 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); } var withdrawActivityInstance = lastActivityInstanceList[0]; if (withdrawActivityInstance.EndedByUserID != runner.UserID) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_NotCreatedByMine; result.Message = string.Format("上一步节点的任务办理人跟当前登录用户不一致,无法撤销回上一步!节点办理人:{0}", withdrawActivityInstance.EndedByUserName); return(rmins); } if (withdrawActivityInstance.ActivityType == (short)ActivityTypeEnum.EndNode) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_PreviousIsEndNode; result.Message = "上一步是结束节点,无法撤销!"; return(rmins); } if (withdrawActivityInstance.ComplexType != null && (withdrawActivityInstance.ComplexType.Value == (short)ComplexTypeEnum.SignTogether || withdrawActivityInstance.ComplexType.Value == (short)ComplexTypeEnum.SignForward)) { //上一步节点是会签(或加签)节点,当前节点是会签节点的下一节点 //会签节点是里程碑节点,不允许可以被撤销,即会签节点的最后一个办理人不能撤销已经完成的会签任务 //但是可以做【退回】处理,退回时整个会签节点重新执行,这样避免会签任务的单个人随意操作。 result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_SignTogetherNotAllowed; result.Message = "会签(或加签)已经发送出去(里程碑节点),不能撤销;但可由下一步操作人退回,重新开始所有人的会签(或加签)!"; return(rmins); } //准备撤销节点的相关信息 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(withdrawActivityInstance.ActivityGUID); rmins.BackwardContext.BackwardToTaskActivityInstance = withdrawActivityInstance; rmins.BackwardContext.BackwardFromActivity = processModel.GetActivity(runningNode.ActivityGUID); rmins.BackwardContext.BackwardFromActivityInstance = runningNode; //准备状态的接收节点 rmins.BackwardContext.BackwardTaskReciever = WfBackwardTaskReciever.Instance( withdrawActivityInstance.ActivityName, withdrawActivityInstance.EndedByUserID, withdrawActivityInstance.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( withdrawActivityInstance.ActivityGUID, runner.UserID, runner.UserName); rmins.ActivityResource = new ActivityResource(runner, rmins.AppRunner.NextActivityPerformers); return(rmins); }
/// <summary> /// 撤销操作 /// 包括: /// 1) 正常流转 /// 2) 多实例节点流转 /// </summary> /// <param name="appName"></param> /// <param name="appInstanceID"></param> /// <param name="processGUID"></param> /// <param name="userID"></param> /// <param name="userName"></param> /// <param name="result"></param> /// <returns></returns> public static WfRuntimeManager CreateRuntimeInstanceWithdraw(WfAppRunner runner, ref WfExecutedResult result) { WfRuntimeManager rmins = null; //获取当前运行节点信息 var aim = new ActivityInstanceManager(); var runningNode = aim.GetRunningNode(runner); var processInstance = (new ProcessInstanceManager()).GetById(runningNode.ProcessInstanceID); var processModel = (new ProcessModel(processInstance.ProcessGUID, processInstance.Version)); if ((runningNode == null) || (runningNode.ActivityState != (short)ActivityStateEnum.Ready)) { 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 && runningNode.MIHostActivityInstanceID.Value > 0) { //获取同一会签主节点下的前置节点信息 var previousActivityInstance = aim.GetPreviousOfMultipleInstanceNode( runningNode.MIHostActivityInstanceID.Value, runningNode.ID, runningNode.CompleteOrder.Value); if (previousActivityInstance != null && previousActivityInstance.EndedByUserID == runner.UserID) { //返回多实例节点下的处理模式 rmins = new WfRuntimeManagerWithdrawMI(); rmins.WfExecutedResult = result = new WfExecutedResult(); rmins.BackwardContext.ProcessInstance = processInstance; rmins.BackwardContext.BackwardToTaskActivity = processModel.GetActivity(previousActivityInstance.ActivityGUID); rmins.BackwardContext.BackwardToTaskActivityInstance = previousActivityInstance; rmins.BackwardContext.BackwardFromActivityInstance = runningNode; //准备状态的接收节点 rmins.BackwardContext.BackwardTaskReciever = WfBackwardTaskReciever.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; } } //以下部分是处理非多实例节点的情况 //正常流转过程,无会签加签等特殊场景 rmins = new WfRuntimeManagerWithdraw(); rmins.WfExecutedResult = result = new WfExecutedResult(); //获取上一步流转节点信息,可能经过And, Or等路由节点 var tim = new TransitionInstanceManager(); bool hasGatewayNode = false; var lastActivityInstanceList = tim.GetPreviousActivityInstance(runningNode, 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); } var withdrawActivityInstance = lastActivityInstanceList[0]; if (withdrawActivityInstance.EndedByUserID != runner.UserID) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_NotCreatedByMine; result.Message = string.Format("上一步节点的任务办理人跟当前登录用户不一致,无法撤销回上一步!节点办理人:{0}", withdrawActivityInstance.EndedByUserName); return rmins; } if (withdrawActivityInstance.ActivityType == (short)ActivityTypeEnum.EndNode) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_PreviousIsEndNode; result.Message = "上一步是结束节点,无法撤销!"; return rmins; } if (withdrawActivityInstance.ComplexType != null && (withdrawActivityInstance.ComplexType.Value == (short)ComplexTypeEnum.SignTogether || withdrawActivityInstance.ComplexType.Value == (short) ComplexTypeEnum.SignForward)) { //上一步节点是会签(或加签)节点,当前节点是会签节点的下一节点 //会签节点是里程碑节点,不允许可以被撤销,即会签节点的最后一个办理人不能撤销已经完成的会签任务 //但是可以做【退回】处理,退回时整个会签节点重新执行,这样避免会签任务的单个人随意操作。 result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_SignTogetherNotAllowed; result.Message = "会签(或加签)已经发送出去(里程碑节点),不能撤销;但可由下一步操作人退回,重新开始所有人的会签(或加签)!"; return rmins; } //准备撤销节点的相关信息 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(withdrawActivityInstance.ActivityGUID); rmins.BackwardContext.BackwardToTaskActivityInstance = withdrawActivityInstance; rmins.BackwardContext.BackwardFromActivity = processModel.GetActivity(runningNode.ActivityGUID); rmins.BackwardContext.BackwardFromActivityInstance = runningNode; //准备状态的接收节点 rmins.BackwardContext.BackwardTaskReciever = WfBackwardTaskReciever.Instance( withdrawActivityInstance.ActivityName, withdrawActivityInstance.EndedByUserID, withdrawActivityInstance.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( withdrawActivityInstance.ActivityGUID, runner.UserID, runner.UserName); rmins.ActivityResource = new ActivityResource(runner, rmins.AppRunner.NextActivityPerformers); return rmins; }