예제 #1
0
        /// <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();

            WithdrawOpertaionTypeEnum withdrawOperation = WithdrawOpertaionTypeEnum.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 = WithdrawOpertaionTypeEnum.Normal;
            }
            else if (runningActivityInstanceList.Count() > 1)       //有多个并行运行节点存在
            {
                //有其它非多实例的并行节点,暂时不处理,后期实现该功能
                result.Status        = WfExecutedStatus.Exception;
                result.ExceptionType = WfExceptionType.Withdraw_HasTooMany;
                result.Message       = "有多个可以撤销回去的节点,而且不是多实例节点,此功能暂时不支持!";

                return(rmins);
            }

            //根据不同分支场景,创建不同撤销运行时管理器
            return(CreateRuntimeInstanceWithdrawByCase(runningActivityInstanceList, withdrawOperation, runner, ref result));
        }
예제 #2
0
        /// <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,
            WithdrawOpertaionTypeEnum 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);

            //以下处理,需要知道上一步是独立节点的信息
            //获取上一步流转节点信息,可能经过And, Or等路由节点
            var  tim            = new TransitionInstanceManager();
            bool hasGatewayNode = false;
            var  currentNode    = runningNode;

            var lastActivityInstanceList = tim.GetPreviousActivityInstance(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 == WithdrawOpertaionTypeEnum.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.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);
            }

            //如果有其它模式,没有处理到,则直接抛出异常
            throw new WorkflowException("未知的撤销场景,请报告给技术支持人员!");
        }