Esempio n. 1
0
        /// <summary>
        /// 执行审批流程中的命令WorkflowCommand
        /// </summary>
        /// <param name="processId"></param>
        /// <param name="identityId">执行该命令的用户ID</param>
        /// <param name="impersonatedIdentityId">针对谁执行的,对方的用户ID,因为审批流程中的活动总是在两个或者多个人之间流转的
        /// 如果一个人执行活动,并同时向多个人分发,怎么办,例如 会签的情况
        /// </param>
        /// <param name="command"></param>
        public void ExecuteCommand(Guid processId, Guid identityId, Guid impersonatedIdentityId, WorkflowCommand command)
        {
            //TODO Workflow Temporary
            //if (!command.Validate())
            //    throw new CommandNotValidException();

            var processInstance = Builder.GetProcessInstance(processId);

            SetProcessNewStatus(processInstance, ProcessStatus.Running);

            IEnumerable <TransitionDefinition> transitions;


            try
            {
                //根据当前的流程实例填写系统定义的流程参数及参数值,系统要统一维护该参数值,
                //以保证状态和流程的运转
                PersistenceProvider.FillSystemProcessParameters(processInstance);

                if (processInstance.CurrentActivityName != command.ValidForActivityName)
                {
                    throw new CommandNotValidForStateException();
                }

                transitions =
                    processInstance.ProcessScheme.GetCommandTransitionForActivity(
                        processInstance.ProcessScheme.FindActivity(processInstance.CurrentActivityName),
                        command.CommandName);

                if (!transitions.Any())
                {
                    throw new InvalidOperationException();
                }
            }
            catch (Exception ex)
            {
                SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                throw;
            }

            //命令需要的参数及参数值
            var parametersLocal = new List <ParameterDefinitionWithValue>();

            try
            {
                foreach (var commandParameter in command.Parameters)
                {
                    //从processInstance获取命令需要的参数值
                    var parameterDefinition = processInstance.ProcessScheme.GetParameterDefinition(commandParameter.Name);

                    if (parameterDefinition != null)
                    {
                        parametersLocal.Add(ParameterDefinition.Create(parameterDefinition, commandParameter.Value));
                    }
                }

                parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterCurrentCommand,
                                                               (object)command.CommandName));
                parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterIdentityId, identityId));
                parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterImpersonatedIdentityId,
                                                               impersonatedIdentityId));
                parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterSchemeId,
                                                               processInstance.SchemeId));

                parametersLocal.ForEach(processInstance.AddParameter);
                //保存运行前的状态
                PersistenceProvider.SavePersistenceParameters(processInstance);
                PersistenceProvider.FillPersistedProcessParameters(processInstance);
            }
            catch (Exception)
            {
                SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                throw;
            }

            var newExecutionParameters = new List <ExecutionRequestParameters>();

            newExecutionParameters.AddRange(
                transitions.Select(
                    at =>
                    ExecutionRequestParameters.Create(processInstance.ProcessId, processInstance.ProcessParameters, at)));

            try
            {
                Bus.QueueExecution(newExecutionParameters);
            }
            catch (Exception ex)
            {
                Logger.Log.Error(string.Format("Error Execute Command Workflow Id={0}", processInstance.ProcessId), ex);
                SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                throw;
            }
        }