Esempio n. 1
0
		public void Throwing_an_exception_from_an_event_handler()
		{
			_workflow = StateMachineWorkflow.New<SubjectWorkflow, Subject>(x =>
				{
					x.AccessCurrentState(y => y.CurrentState);

					x.Initially()
						.When(e => e.Create)
						.Then(i => i.Create)
						.TransitionTo(s => s.Created)
						.InCaseOf()
						.Exception<SubjectException>()
						.Then(i =>
							{
								_instanceHandlerCalled = true;
							})
						.Then(() => _handlerCalled = true)
						.TransitionTo(s => s.Failed);
				});

			_subject = new Subject();

			_instance = _workflow.GetInstance(_subject);

			_instance.RaiseEvent(x => x.Create);
		}
Esempio n. 2
0
 /// <summary>
 /// 创建工作流实例
 /// </summary>
 /// <param name="p"></param>
 /// <returns></returns>
 public static WorkflowInstance CreateInstance(Process p, IWorkflowParser parser)
 {
     var workflow = parser.Parse(GetCacheKey(p.ProcessType)
         , p.ProcessType.Workflow.Serialized
         , p.ProcessType.ActivitySettings);
     var instance = new WorkflowInstance(workflow, p.ID, p.GetInputs());
     //HACK:【重要】强制让Core调度使用同步上下文进行调度而不使用Threaded模式,使得事务与resumption嵌套,便于事务控制和错误处理 20120507
     instance.SynchronizationContext = new WorkflowInstance.DefaultSynchronizationContext();
     //标记为可持久化
     instance.IsPersistable = true;
     //数据字段扩展
     instance.Extensions.Add<DataFieldExtension>(WorkflowBuilder.CreateDataFieldExtension(p));
     //自定义节点扩展
     instance.Extensions.Add<CustomExtension>(new CustomExtension(p.ProcessType.ActivitySettings
         .Where(o => o is CustomSetting)
         .Select(o => o as CustomSetting)
         .ToList()));
     //人工节点扩展
     instance.Extensions.Add<HumanExtension>(new HumanExtension());
     //服务端节点扩展
     instance.Extensions.Add<ServerExtension>(new ServerExtension());
     //并行节点扩展
     instance.Extensions.Add<ParallelExtension>(new ParallelExtension());
     //子流程节点扩展
     instance.Extensions.Add<SubProcessExtension>(new SubProcessExtension());
     return instance;
 }
        internal DebugManager(Activity root, string moduleNamePrefix, string typeNamePrefix, string auxiliaryThreadName, bool breakOnStartup, 
            WorkflowInstance host, bool debugStartedAtRoot, bool resetDynamicModule)
        {
            if (resetDynamicModule)
            {
                dynamicModuleManager = null;
            }

            if (dynamicModuleManager == null)
            {
                dynamicModuleManager = new StateManager.DynamicModuleManager(moduleNamePrefix);
            }

            this.stateManager = new StateManager(
                new StateManager.Properties
                    {
                        ModuleNamePrefix = moduleNamePrefix,
                        TypeNamePrefix = typeNamePrefix,
                        AuxiliaryThreadName = auxiliaryThreadName,
                        BreakOnStartup = breakOnStartup
                    },
                    debugStartedAtRoot, dynamicModuleManager);
            
            this.states = new Dictionary<object, State>();
            this.runningThreads = new Dictionary<int, Stack<Activity>>();
            this.instrumentationTracker = new InstrumentationTracker(root);
            this.host = host;
        }
Esempio n. 4
0
        /// <summary>
        /// 实例化审批页面选择对象
        /// </summary>
        /// <param name="instance"></param>
        public ApproveSelector(WorkflowInstance instance)
            : this()
        {
            var currentActi = instance.GetCurrentActi();
            foreach (var choice in currentActi.Transitions.Keys) {
                var nextActi = currentActi.Transitions[choice];
                if (nextActi == null) {
                    throw new NextActivityNotFoundException(instance.InstanceNo, instance.CurrentActivity, choice);
                }
                var actor = nextActi.Actor;
                this.m_NextChoice.Add(choice);
                this.m_Activities.Add(choice, nextActi.Name);

                IEnumerable<IUser> users = new List<IUser>();
                if (actor != null) {
                    if (choice.Contains("退回")) {
                        actor.RefActivityName = nextActi.Name;
                        users = actor.Resolve(instance);
                    } else {
                        users = actor.Resolve(instance);
                    }
                }

                foreach (var user in users) {
                    var organization = SecurityContext.Provider.GetOrganization(user.DeptId);
                    this[choice].Add(new SelectorUser() {
                        id = user.Id,
                        name = user.Name,
                        deptName = organization.FullName
                    });
                }
            }
        }
Esempio n. 5
0
        /// <summary>Creates an workflow instance based on this workflow definition. </summary>
        /// <returns>The <see cref="WorkflowInstance"/>. </returns>
        /// <exception cref="WorkflowException">A workflow validation exception occurred. </exception>
        public WorkflowInstance CreateInstance()
        {
            ValidateRoutes();

            var instance = new WorkflowInstance(this, new List<ActivityData>());
            instance.CurrentActivityIds.Add(StartActivityId);
            return instance;
        }
Esempio n. 6
0
		public void Creating_a_new_workflow()
		{
			_workflow = StateMachineWorkflow.New<TestWorkflow, TestInstance>(x =>
				{
					x.AccessCurrentState(y => y.CurrentState);
				});

			_instance = _workflow.GetInstance(new TestInstance());
		}
Esempio n. 7
0
        public void Human()
        {
            Taobao.Activities.Hosting.WorkflowInstance.IsEnableDebug = true;

            var app = new WorkflowInstance(new HumanWorkflow(), null);
            app.Extensions.Add<HumanExtension>(new HumanExtension());
            app.Extensions.Add<CustomExtension>(new CustomExtension(new List<CustomSetting>() { new ServerSetting(0, "节点1", "", "", null, null, false) }));
            app.Extensions.Add<DataFieldExtension>(new DataFieldExtension("", 0, null));
            app.Run();

            Thread.Sleep(1000);
        }
 public DebugManager(Activity root, string moduleNamePrefix, string typeNamePrefix, string auxiliaryThreadName, bool breakOnStartup, WorkflowInstance host, bool debugStartedAtRoot)
 {
     StateManager.Properties properties = new StateManager.Properties {
         ModuleNamePrefix = moduleNamePrefix,
         TypeNamePrefix = typeNamePrefix,
         AuxiliaryThreadName = auxiliaryThreadName,
         BreakOnStartup = breakOnStartup
     };
     this.stateManager = new StateManager(properties, debugStartedAtRoot);
     this.states = new Dictionary<object, System.Activities.Debugger.State>();
     this.runningThreads = new Dictionary<int, Stack<Activity>>();
     this.instrumentationTracker = new InstrumentationTracker(root);
     this.host = host;
 }
Esempio n. 9
0
		public void An_event_causing_a_state_transition()
		{
			_workflow = StateMachineWorkflow.New<TestWorkflow, TestInstance>(x =>
				{
					x.AccessCurrentState(y => y.CurrentState);

					x.During(y => y.Initial)
						.When(y => y.Finish)
						.TransitionTo(y => y.Completed);
				});

			_instance = _workflow.GetInstance(new TestInstance());

			_instance.RaiseEvent(x => x.Finish);
		}
        public void CtorShouldCreateTracker()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);

                // Act
                var wi = new WorkflowInstance(model);

                // Assert
                Assert.IsNotNull(wi.StateTracker);
            }
        }
        public void HostIsNotNull()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);
                var wi = new WorkflowInstance(model);

                // Act
                wi.New();

                // Assert
                Assert.IsNotNull(wi.Host);
            }
        }
Esempio n. 12
0
        /// <summary>
        /// 传阅流程
        /// </summary>
        /// <param name="instance">流程实例.</param>
        /// <param name="toUsers">传阅用户.</param>
        public override bool PassAround(WorkflowInstance instance, IList<IUser> toUsers)
        {
            var tobeReadWorkItems = new List<K2WorkflowItem>();
            var currentWorkItem = instance.CurrentWorkItem;

            #region 添加下一环节待阅流程

            var lastTaskId = this.GetWorkItemLastTaskId(instance.InstanceNo);
            foreach (var user in toUsers) {
                var workItem = WorkflowItemFactory.Create<K2WorkflowItem>();
                lastTaskId += 1;
                workItem.TaskId = lastTaskId;
                workItem.InstanceNo = instance.InstanceNo;
                workItem.PartId = user.Id;
                workItem.PartName = user.Name;
                workItem.PartDeptId = user.DeptId;
                var dept = SecurityContext.Provider.GetOrganization(user.DeptId);
                workItem.PartDeptName = (dept == null ? "" : dept.FullName);
                workItem.ReceTime = DateTime.Now;
                workItem.TaskStatus = TaskStatus.ToRead;
                workItem.CurrentActi = currentWorkItem.CurrentActi;
                // 传阅人
                workItem.Mandatary = CurrentUser.Name;
                workItem.MandataryId = CurrentUser.Id;

                tobeReadWorkItems.Add(workItem);
            }

            #endregion

            using (var transactionScope = new TransactionScope(TransactionScopeOption.Required)) {
                // 新增传阅环节
                foreach (var workitem in tobeReadWorkItems) {
                    _dao.Insert<K2WorkflowItem>(workitem);
                }
                transactionScope.Complete();
            }

            return true;
        }
Esempio n. 13
0
		public void A_message_event_is_raised()
		{
			_workflow = StateMachineWorkflow.New<TestWorkflow, TestInstance>(x =>
			{
				x.AccessCurrentState(y => y.CurrentState);

				x.During(y => y.Initial)
					.When(y => y.Finish)
					.Then(() => _nonInstanceValue = true)
					.Then(instance => instance.MessageValue = "Success")
					.Then((instance, message) => instance.MessageValue = message.Value)
					.TransitionTo(y => y.Completed);
			});

			_testInstance = new TestInstance();

			_instance = _workflow.GetInstance(_testInstance);

			_instance.RaiseEvent(x => x.Finish, new Result
			{
				Value = "Success"
			});
		}
Esempio n. 14
0
        /// <summary>
        /// 初始化流程表单对象
        /// </summary>
        /// <param name="instance">流程实例</param>
        /// <returns></returns>
        public static WorkflowForm Init(WorkflowInstance instance)
        {
            var currentUser = SecurityContext.User;

            var form = new WorkflowForm();
            form.Instance = instance;
            form.AppCode = instance.AppCode;
            form.AppName = instance.AppName;
            form.Description = instance.Description;
            form.VersionStr = instance.Version.ToString(CultureInfo.InvariantCulture);
            form.InstanceNo = instance.InstanceNo;
            #region FormStatus
            switch (instance.Status) {
                case InstanceStatus.Draft:
                    {
                        form.Status = FormStatus.Draft;
                        break;
                    }
                case InstanceStatus.Running:
                    {
                        var currentWorkItem = instance.CurrentWorkItem;
                        // 待办条件:当前环节的审批人为当前登录用户 && 当前环节未结束
                        if ((currentWorkItem.PartId.Equals(currentUser.Id, StringComparison.OrdinalIgnoreCase)
                            || (!string.IsNullOrEmpty(currentWorkItem.MandataryId) && currentWorkItem.MandataryId.Equals(currentUser.Id, StringComparison.OrdinalIgnoreCase))
                            || DelegateWork.IsDelegate(instance.AppCode, currentWorkItem.PartId, currentUser.Id))
                            && currentWorkItem.TaskStatus == TaskStatus.Waiting) {
                            form.Status = FormStatus.Todo;
                        } else {
                            form.Status = FormStatus.Done;
                        }
                        break;
                    }
                case InstanceStatus.Cancel:
                case InstanceStatus.Deleted:
                case InstanceStatus.Finished:
                    {
                        form.Status = FormStatus.Done;
                        break;
                    }
            }
            #endregion
            form.Creator = SecurityContext.Provider.Get(instance.CreatorId);
            form.CreatorDept = SecurityContext.Provider.GetOrganization(form.Creator.DeptId);
            form.CurrentUser = SecurityContext.User;
            form.TaskId = instance.CurrentWorkItem == null ? 1 : instance.CurrentWorkItem.TaskId;
            form.CurrentActi = instance.CurrentWorkItem == null ? instance.CurrentActivity : instance.CurrentWorkItem.CurrentActi;
            form.Controller = FlowFactory.GetWorklfowControllerName(form.AppCode);
            form.Instance = instance;

            // 根据WorkItem中的环节信息计算出历史环节(Distinct)
            // 获取并添加到List中,用于渲染
            var workItems = instance.GetWorkItems();
            if (workItems != null && workItems.Any()) {
                var lastTaskId = workItems.First(p => p.CurrentActi.Equals(form.CurrentActi, StringComparison.OrdinalIgnoreCase)).TaskId;
                var activities = workItems.Where(p => p.TaskId <= lastTaskId).OrderBy(p => p.TaskId);
                foreach (var activity in activities) {
                    if (form.HistoryActivities.Contains(activity.CurrentActi)) {
                        continue;
                    }
                    form.HistoryActivities.Add(activity.CurrentActi);
                }
            }
            if (form.HistoryActivities.Count == 0) {
                form.HistoryActivities.Add(form.CurrentActi);
            }

            return form;
        }
        public void IdIsNotEmptyGuid()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);
                var wi = new WorkflowInstance(model);

                // Act
                var id = wi.Id;

                // Assert
                Assert.AreEqual(Guid.Empty, id);
            }
        }
Esempio n. 16
0
        private async Task ExecuteStep(WorkflowInstance workflow, WorkflowStep step, ExecutionPointer pointer, WorkflowExecutorResult wfResult, WorkflowDefinition def, CancellationToken cancellationToken = default)
        {
            IStepExecutionContext context = new StepExecutionContext
            {
                Workflow          = workflow,
                Step              = step,
                PersistenceData   = pointer.PersistenceData,
                ExecutionPointer  = pointer,
                Item              = pointer.ContextItem,
                CancellationToken = cancellationToken
            };

            using (var scope = _scopeProvider.CreateScope(context))
            {
                _logger.LogDebug("Starting step {0} on workflow {1}", step.Name, workflow.Id);

                IStepBody body         = step.ConstructBody(scope.ServiceProvider);
                var       stepExecutor = scope.ServiceProvider.GetRequiredService <IStepExecutor>();

                if (body == null)
                {
                    _logger.LogError("Unable to construct step body {0}", step.BodyType.ToString());
                    pointer.SleepUntil = _datetimeProvider.UtcNow.Add(_options.ErrorRetryInterval);
                    wfResult.Errors.Add(new ExecutionError
                    {
                        WorkflowId         = workflow.Id,
                        ExecutionPointerId = pointer.Id,
                        ErrorTime          = _datetimeProvider.UtcNow,
                        Message            = $"Unable to construct step body {step.BodyType}"
                    });
                    return;
                }

                foreach (var input in step.Inputs)
                {
                    input.AssignInput(workflow.Data, body, context);
                }

                switch (step.BeforeExecute(wfResult, context, pointer, body))
                {
                case ExecutionPipelineDirective.Defer:
                    return;

                case ExecutionPipelineDirective.EndWorkflow:
                    workflow.Status       = WorkflowStatus.Complete;
                    workflow.CompleteTime = _datetimeProvider.UtcNow;
                    return;
                }

                var result = await stepExecutor.ExecuteStep(context, body);

                if (result.Proceed)
                {
                    foreach (var output in step.Outputs)
                    {
                        output.AssignOutput(workflow.Data, body, context);
                    }
                }

                _executionResultProcessor.ProcessExecutionResult(workflow, def, pointer, step, result, wfResult);
                step.AfterExecute(wfResult, context, result, pointer);
            }
        }
 public WorkflowInstancePipeBind(WorkflowInstance instance)
 {
     _instance = instance;
 }
Esempio n. 18
0
        internal static WorkflowInstance ToWorkflowInstance(this PersistedWorkflow instance)
        {
            WorkflowInstance result = new WorkflowInstance();

            result.Data                 = JsonConvert.DeserializeObject(instance.Data, SerializerSettings);
            result.Description          = instance.Description;
            result.Reference            = instance.Reference;
            result.Id                   = instance.InstanceId.ToString();
            result.NextExecution        = instance.NextExecution;
            result.Version              = instance.Version;
            result.WorkflowDefinitionId = instance.WorkflowDefinitionId;
            result.Status               = instance.Status;
            result.CreateTime           = DateTime.SpecifyKind(instance.CreateTime, DateTimeKind.Utc);
            if (instance.CompleteTime.HasValue)
            {
                result.CompleteTime = DateTime.SpecifyKind(instance.CompleteTime.Value, DateTimeKind.Utc);
            }

            foreach (var ep in instance.ExecutionPointers)
            {
                var pointer = new ExecutionPointer();
                result.ExecutionPointers.Add(pointer);

                pointer.Id     = ep.Id;
                pointer.StepId = ep.StepId;
                pointer.Active = ep.Active;

                if (ep.SleepUntil.HasValue)
                {
                    pointer.SleepUntil = DateTime.SpecifyKind(ep.SleepUntil.Value, DateTimeKind.Utc);
                }

                pointer.PersistenceData = JsonConvert.DeserializeObject(ep.PersistenceData ?? string.Empty, SerializerSettings);

                if (ep.StartTime.HasValue)
                {
                    pointer.StartTime = DateTime.SpecifyKind(ep.StartTime.Value, DateTimeKind.Utc);
                }

                if (ep.EndTime.HasValue)
                {
                    pointer.EndTime = DateTime.SpecifyKind(ep.EndTime.Value, DateTimeKind.Utc);
                }

                pointer.StepName = ep.StepName;

                pointer.RetryCount    = ep.RetryCount;
                pointer.PredecessorId = ep.PredecessorId;
                pointer.ContextItem   = JsonConvert.DeserializeObject(ep.ContextItem ?? string.Empty, SerializerSettings);

                if (!string.IsNullOrEmpty(ep.Children))
                {
                    pointer.Children = ep.Children.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                }

                pointer.EventName      = ep.EventName;
                pointer.EventKey       = ep.EventKey;
                pointer.EventPublished = ep.EventPublished;
                pointer.EventData      = JsonConvert.DeserializeObject(ep.EventData ?? string.Empty, SerializerSettings);
                pointer.Outcome        = JsonConvert.DeserializeObject(ep.Outcome ?? string.Empty, SerializerSettings);
                pointer.Status         = ep.Status;

                if (!string.IsNullOrEmpty(ep.Scope))
                {
                    pointer.Scope = new Stack <string>(ep.Scope.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
                }

                foreach (var attr in ep.ExtensionAttributes)
                {
                    pointer.ExtensionAttributes[attr.AttributeKey] = JsonConvert.DeserializeObject(attr.AttributeValue, SerializerSettings);
                }
            }

            return(result);
        }
Esempio n. 19
0
        public async Task <WorkflowExecutorResult> Execute(WorkflowInstance workflow, CancellationToken cancellationToken = default)
        {
            var wfResult = new WorkflowExecutorResult();

            var exePointers = new List <ExecutionPointer>(workflow.ExecutionPointers.Where(x => x.Active && (!x.SleepUntil.HasValue || x.SleepUntil < _datetimeProvider.UtcNow)));
            var def         = _registry.GetDefinition(workflow.WorkflowDefinitionId, workflow.Version);

            if (def == null)
            {
                _logger.LogError("Workflow {0} version {1} is not registered", workflow.WorkflowDefinitionId, workflow.Version);
                return(wfResult);
            }

            _cancellationProcessor.ProcessCancellations(workflow, def, wfResult);

            foreach (var pointer in exePointers)
            {
                if (!pointer.Active)
                {
                    continue;
                }

                var step = def.Steps.FindById(pointer.StepId);
                if (step == null)
                {
                    _logger.LogError("Unable to find step {0} in workflow definition", pointer.StepId);
                    pointer.SleepUntil = _datetimeProvider.UtcNow.Add(_options.ErrorRetryInterval);
                    wfResult.Errors.Add(new ExecutionError
                    {
                        WorkflowId         = workflow.Id,
                        ExecutionPointerId = pointer.Id,
                        ErrorTime          = _datetimeProvider.UtcNow,
                        Message            = $"Unable to find step {pointer.StepId} in workflow definition"
                    });
                    continue;
                }

                WorkflowActivity.Enrich(step);
                try
                {
                    if (!InitializeStep(workflow, step, wfResult, def, pointer))
                    {
                        continue;
                    }

                    await ExecuteStep(workflow, step, pointer, wfResult, def, cancellationToken);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Workflow {0} raised error on step {1} Message: {2}", workflow.Id, pointer.StepId, ex.Message);
                    wfResult.Errors.Add(new ExecutionError
                    {
                        WorkflowId         = workflow.Id,
                        ExecutionPointerId = pointer.Id,
                        ErrorTime          = _datetimeProvider.UtcNow,
                        Message            = ex.Message
                    });

                    _executionResultProcessor.HandleStepException(workflow, def, pointer, step, ex);
                    Host.ReportStepError(workflow, step, ex);
                }
                _cancellationProcessor.ProcessCancellations(workflow, def, wfResult);
            }
            ProcessAfterExecutionIteration(workflow, def, wfResult);
            await DetermineNextExecutionTime(workflow, def);

            using (var scope = _serviceProvider.CreateScope())
            {
                var middlewareRunner = scope.ServiceProvider.GetRequiredService <IWorkflowMiddlewareRunner>();
                await middlewareRunner.RunExecuteMiddleware(workflow, def);
            }

            return(wfResult);
        }
Esempio n. 20
0
        /// <summary>
        /// يك فرآيند جديد را آغاز ميكند
        /// </summary>
        /// <param name="InstanceID">شناسه فرآيند جديد</param>
        /// <param name="WorkflowCode">كدفرآيند</param>
        /// <param name="EntityID">شناسه موجوديت</param>
        /// <param name="ExtraInfo">اطلاعات اضافه</param>
        /// <param name="UserName">نام كاربري ايجاد كننده</param>
        /// <param name="ds">ديتاست</param>
        public void CreateWorkflowInstance(WorkflowInstance wfInstance, string userName, string firstPerformer, string extraInfo, int priorityNo, bool isAuthoforward = false)
        {
            try
            {
                //if (wfs.IsWorkflowCreatedBefore(this.WorkflowID, wfInstance.EntityID))
                //    throw new WFUserException("براي اين موجوديت قبلا ورك فلو ثبت شده است.");

                Workflow wf = wfs.GetWorkflowByID(this.WorkflowID);

                wfInstance.InsertUser = userName;
                wfInstance.InsertDate = DateTime.Now;
                wfInstance.WorkflowID = this.WorkflowID;
                wfInstance.WorkflowInstanceStatusID = (int)WorkflowInstanceStatusEnum.Waiting;
                wfInstance.ExtraInfo = extraInfo;

                if (string.IsNullOrEmpty(wfInstance.WorkflowInstanceTitle))
                {
                    wfInstance.WorkflowInstanceTitle = wf.WorkflowTitle;
                }
                if (string.IsNullOrEmpty(wfInstance.EntityName))
                {
                    wfInstance.EntityName = wf.EntityName;
                }
                if (string.IsNullOrEmpty(wfInstance.EntityTitle))
                {
                    wfInstance.EntityTitle = wf.EntityTitle;
                }
                if (string.IsNullOrEmpty(wfInstance.EntityUrl))
                {
                    wfInstance.EntityUrl = wf.EntityUrl;
                }

                // inserting to database
                var ObjectContext = wfs.ObjectContext;
                var task          = (from o in ObjectContext.Task
                                     where (o.TaskTypeID == 0 && o.WorkflowID == this.WorkflowID) // فعاليت آغازين
                                     select o).First();

                TaskInstance ti = new TaskInstance();
                ti.TaskInstanceID     = Guid.NewGuid();
                ti.PriorityID         = priorityNo;
                ti.WorkflowInstanceID = wfInstance.WorkflowInstanceID;
                ti.TaskID             = task.TaskID;
                ti.TaskCode           = task.TaskCode;
                ti.TaskTitle          = task.TaskTitle;
                if (string.IsNullOrEmpty(firstPerformer) == false)
                {
                    ti.PerformerID = firstPerformer;
                }
                else if (string.IsNullOrEmpty(task.PerformerID) == false)
                {
                    ti.PerformerID = task.PerformerID;
                }
                //else
                //    throw new Exception("PerformerID is not selected");
                ti.EntityName  = wfInstance.EntityName;
                ti.EntityID    = wfInstance.EntityID;
                ti.EntityTitle = wfInstance.EntityTitle;
                ti.EntityUrl   = wfInstance.EntityUrl;
                //ti.EntityDateTime = wfInstance.entitydat
                ti.InsertUser           = userName;
                ti.InsertDate           = DateTime.Now;
                ti.TaskInstanceStatusID = (int)TaskInstanceStatusEnum.Waiting; // در حال انتظار
                ti.NotificationStatusID = (int)NotificationStatusEnum.Waiting; // در حال انتظار
                //ti.ExtraInt = isauthoforward;
                ti.ExtraInt2 = isAuthoforward ? 1 : 0;
                CreateWorkflowEventArgs WorkflowEventArg = new CreateWorkflowEventArgs(wfInstance, ti, userName);
                OnBeforeCreateWorkflow(WorkflowEventArg);

                ObjectContext.WorkflowInstance.AddObject(wfInstance);
                ObjectContext.TaskInstance.AddObject(ti);

                OnAfterCreateWorkflow(WorkflowEventArg);

                ObjectContext.SaveChanges();
            }
            catch (Exception)
            {
                throw;
            }
        }
        public void IdIsHostId()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);
                var wi = new WorkflowInstance(model);

                // Act
                wi.New();
                var hostid = wi.Host.Id;
                var id = wi.Id;

                // Assert
                Assert.AreEqual(hostid, id);
            }
        }
Esempio n. 22
0
        public async Task <string> CreateNewWorkflow(WorkflowInstance workflow)
        {
            await WorkflowInstances.InsertOneAsync(workflow);

            return(workflow.Id);
        }
Esempio n. 23
0
 private WorkflowInstanceDocument Map(WorkflowInstance source) => mapper.Map <WorkflowInstanceDocument>(source);
Esempio n. 24
0
 public async Task PersistWorkflow(WorkflowInstance workflow)
 {
     await WorkflowInstances.ReplaceOneAsync(x => x.Id == workflow.Id, workflow);
 }
        /// <summary>
        /// 用途:创建流程实例并返回首个流程活动工作项
        /// 约定:
        /// 1、一个流程有且仅有一个根活动
        /// 2、代理人不能发起委托人的新流程,只能处理委托日期后正在流转的流程数据
        /// 3、有发起流程模型权限方可以操作
        /// </summary>
        /// <param name="workflowGuid">流程模型guid</param>
        /// <returns>首个流程活动工作项</returns>
        public ResponseByWorkitem CreateWorkflowInstance(string workflowGuid, string name = null)
        {
            ///创建流程实例
            WorkflowInstance wfi = new WorkflowInstance(workflowGuid, name);

            //wfi.Guid ...
            //wfi.Name ...
            //wfi.WorkflowGuid ...
            wfi.Author = this.Context.CurUser;
            //wfi.WorkflowState ...
            //wfi.Participator ...
            //wfi.Locker ...
            //wfi.BeginTime ...;
            //wfi.EndTime ...;
            //wfi.DataEntity ...

            wfi.SetContext(this.Context);

            ///加入权限控制
            if (!(this.Context.CurUser.IsAdministrator() ||//是否大管理员
                  wfi.GetWorkflow().IsAdministrators(this.Context.CurUser) ||//是否流程模型管理员
                  wfi.GetWorkflow().IsLegalAuthor(this.Context.CurUser)   //流程的合法发起用户
                  ))
            {
                return(new ResponseByWorkitem()
                {
                    CallBackMessage = new ResultMessage()
                    {
                        State = false, Message = "不能发起流程!"
                    }
                });
            }

            ///开启流程实例服务
            wfi.Start();
            wfi.Save();

            //创建活动实例
            WorkitemInstance wii = new WorkitemInstance(wfi.Guid, wfi.GetWorkflow().GetStartNode());

            //wii.Guid ...
            //wii.Name ...
            //wii.ActivityGuid ...
            //wii.WorkflowInstanceGuid ...
            //wii.AduitContent = "";
            //wii.AduitSign = "";
            //wii.ReadTime = null;
            //wii.NextActivities = null;
            wii.User = this.Context.CurUser;
            //wii.ProxyUser = null;
            //wii.IsProxy = false;
            //wii.WorkitemInstanceState ...
            //wii.FromWorkitemInstanceGuid = "";
            //wii.AttachmentTrainsitions = null;
            //wii.SelectVoteItem = "";
            //wii.OtherVoteItemContent = "";
            //wii.BeginTime ...;
            //wii.EndTime ...;
            //wii.DataEntity ...

            wii.SetContext(this.Context);
            ///开启活动实例
            wii.Start();
            wii.Save();
            ///活动前事件处理
            var rm = wii.BeforeTrigger();

            ResponseByWorkitem response;

            ///如果不满足
            if (!rm.State)
            {
                response = new ResponseByWorkitem()
                {
                    ActivityInstance = wii,
                    //NextMaybeActivities=null,
                    UIRight         = this.Context.Config.RightByReadOnly,
                    CallBackMessage = rm,
                };
            }
            else
            {
                response = new ResponseByWorkitem()
                {
                    ActivityInstance    = wii,
                    NextMaybeActivities = wii.GetNextEffectiveActivities(),
                    UIRight             = wii.GetActivity().UIRight,
                    CallBackMessage     = new ResultMessage()
                    {
                        State = true, Message = ""
                    },
                };
            }
            return(response);
        }
Esempio n. 26
0
        internal static PersistedWorkflow ToPersistable(this WorkflowInstance instance, PersistedWorkflow persistable = null)
        {
            if (persistable == null)
            {
                persistable = new PersistedWorkflow();
            }

            persistable.Data                 = JsonConvert.SerializeObject(instance.Data, SerializerSettings);
            persistable.Description          = instance.Description;
            persistable.Reference            = instance.Reference;
            persistable.InstanceId           = new Guid(instance.Id);
            persistable.NextExecution        = instance.NextExecution;
            persistable.Version              = instance.Version;
            persistable.WorkflowDefinitionId = instance.WorkflowDefinitionId;
            persistable.Status               = instance.Status;
            persistable.CreateTime           = instance.CreateTime;
            persistable.CompleteTime         = instance.CompleteTime;

            foreach (var ep in instance.ExecutionPointers)
            {
                var persistedEP = persistable.ExecutionPointers.FirstOrDefault(x => x.Id == ep.Id);

                if (persistedEP == null)
                {
                    persistedEP = new PersistedExecutionPointer();
                    persistable.ExecutionPointers.Add(persistedEP);
                }

                persistedEP.Id              = ep.Id ?? Guid.NewGuid().ToString();
                persistedEP.StepId          = ep.StepId;
                persistedEP.Active          = ep.Active;
                persistedEP.SleepUntil      = ep.SleepUntil;
                persistedEP.PersistenceData = JsonConvert.SerializeObject(ep.PersistenceData, SerializerSettings);
                persistedEP.StartTime       = ep.StartTime;
                persistedEP.EndTime         = ep.EndTime;
                persistedEP.StepName        = ep.StepName;
                persistedEP.RetryCount      = ep.RetryCount;
                persistedEP.PredecessorId   = ep.PredecessorId;
                persistedEP.ContextItem     = JsonConvert.SerializeObject(ep.ContextItem, SerializerSettings);
                persistedEP.Children        = string.Empty;

                foreach (var child in ep.Children)
                {
                    persistedEP.Children += child + ";";
                }

                persistedEP.EventName      = ep.EventName;
                persistedEP.EventKey       = ep.EventKey;
                persistedEP.EventPublished = ep.EventPublished;
                persistedEP.EventData      = JsonConvert.SerializeObject(ep.EventData, SerializerSettings);
                persistedEP.Outcome        = JsonConvert.SerializeObject(ep.Outcome, SerializerSettings);
                persistedEP.Status         = ep.Status;

                persistedEP.Scope = string.Empty;
                foreach (var item in ep.Scope)
                {
                    persistedEP.Scope += item + ";";
                }

                foreach (var attr in ep.ExtensionAttributes)
                {
                    var persistedAttr = persistedEP.ExtensionAttributes.FirstOrDefault(x => x.AttributeKey == attr.Key);
                    if (persistedAttr == null)
                    {
                        persistedAttr = new PersistedExtensionAttribute();
                        persistedEP.ExtensionAttributes.Add(persistedAttr);
                    }

                    persistedAttr.AttributeKey   = attr.Key;
                    persistedAttr.AttributeValue = JsonConvert.SerializeObject(attr.Value, SerializerSettings);
                }
            }

            return(persistable);
        }
        public void IsLoadedReturnsTrueOnNew()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);
                var wi = new WorkflowInstance(model);
                wi.New();

                // Act
                var actual = wi.IsLoaded;

                // Assert
                Assert.IsTrue(actual);
            }
        }
Esempio n. 28
0
 public Task <string> CreateNewWorkflow(WorkflowInstance workflow, CancellationToken _ = default) => _innerService.CreateNewWorkflow(workflow);
Esempio n. 29
0
        public override void AfterWorkflowIteration(WorkflowExecutorResult executorResult, WorkflowDefinition defintion, WorkflowInstance workflow, ExecutionPointer executionPointer)
        {
            base.AfterWorkflowIteration(executorResult, defintion, workflow, executionPointer);
            var func = _cancelCondition.Compile();

            if (func((TData)workflow.Data))
            {
                executionPointer.EndTime = DateTime.Now.ToUniversalTime();
                executionPointer.Active  = false;
            }
        }
Esempio n. 30
0
 public Task PersistWorkflow(WorkflowInstance workflow, CancellationToken _ = default) => _innerService.PersistWorkflow(workflow);
Esempio n. 31
0
 /// <summary>
 /// 流程传阅
 /// </summary>
 /// <param name="instance">流程实例.</param>
 /// <param name="toUsersId">传阅目标用户.</param>
 public abstract bool PassAround(WorkflowInstance instance, params string[] toUsersId);
Esempio n. 32
0
 public WorkflowNode GetCurrentNode(string instanceID)
 {
     return(WorkflowInstance.GetInstance(instanceID).Current);
 }
Esempio n. 33
0
        public override ExecutionPipelineDirective InitForExecution(WorkflowExecutorResult executorResult, WorkflowDefinition defintion, WorkflowInstance workflow, ExecutionPointer executionPointer)
        {
            if (!executionPointer.EventPublished)
            {
                //resolve principal to be assigned
                var resolvedUser = Principal.Compile().DynamicInvoke(workflow.Data);

                executionPointer.ExtensionAttributes["AssignedPrincipal"] = resolvedUser;
                executionPointer.ExtensionAttributes["Prompt"]            = UserPrompt;

                Dictionary <string, object> userOptions = new Dictionary <string, object>();
                foreach (var outcome in Outcomes)
                {
                    userOptions[outcome.Label ?? Convert.ToString(outcome.GetValue(workflow.Data) ?? "Proceed")] = outcome.GetValue(workflow.Data);
                }
                executionPointer.ExtensionAttributes["UserOptions"] = userOptions;

                executionPointer.EventKey  = workflow.Id + "." + executionPointer.Id;
                executionPointer.EventName = "UserAction";
                executionPointer.Active    = false;

                executorResult.Subscriptions.Add(new EventSubscription()
                {
                    WorkflowId    = workflow.Id,
                    StepId        = executionPointer.StepId,
                    EventName     = executionPointer.EventName,
                    EventKey      = executionPointer.EventKey,
                    SubscribeAsOf = DateTime.Now.ToUniversalTime()
                });

                return(ExecutionPipelineDirective.Defer);
            }
            return(ExecutionPipelineDirective.Next);
        }
Esempio n. 34
0
        public static Dictionary <string, AttributeValue> ToDynamoMap(this WorkflowInstance source)
        {
            var result = new Dictionary <string, AttributeValue>();

            result["id"] = new AttributeValue(source.Id);
            result["workflow_definition_id"] = new AttributeValue(source.WorkflowDefinitionId);
            result["version"]        = new AttributeValue(source.Version.ToString());
            result["next_execution"] = new AttributeValue()
            {
                N = (source.NextExecution ?? 0).ToString()
            };
            result["create_time"] = new AttributeValue()
            {
                N = source.CreateTime.Ticks.ToString()
            };
            result["data"]            = new AttributeValue(JsonConvert.SerializeObject(source.Data, SerializerSettings));
            result["workflow_status"] = new AttributeValue()
            {
                N = Convert.ToInt32(source.Status).ToString()
            };

            if (!string.IsNullOrEmpty(source.Description))
            {
                result["description"] = new AttributeValue(source.Description);
            }

            if (!string.IsNullOrEmpty(source.Reference))
            {
                result["reference"] = new AttributeValue(source.Reference);
            }

            if (source.CompleteTime.HasValue)
            {
                result["complete_time"] = new AttributeValue()
                {
                    N = source.CompleteTime.Value.Ticks.ToString()
                }
            }
            ;

            var pointers = new List <AttributeValue>();

            foreach (var pointer in source.ExecutionPointers)
            {
                pointers.Add(new AttributeValue(JsonConvert.SerializeObject(pointer, SerializerSettings)));
            }

            result["pointers"] = new AttributeValue()
            {
                L = pointers
            };

            if (source.Status == WorkflowStatus.Runnable)
            {
                result["runnable"] = new AttributeValue()
                {
                    N = 1.ToString()
                }
            }
            ;

            return(result);
        }
Esempio n. 35
0
        private async Task DetermineNextExecutionTime(WorkflowInstance workflow, WorkflowDefinition def)
        {
            //TODO: move to own class
            workflow.NextExecution = null;

            if (workflow.Status == WorkflowStatus.Complete)
            {
                return;
            }

            foreach (var pointer in workflow.ExecutionPointers.Where(x => x.Active && (x.Children ?? new List <string>()).Count == 0))
            {
                if (!pointer.SleepUntil.HasValue)
                {
                    workflow.NextExecution = 0;
                    return;
                }

                var pointerSleep = pointer.SleepUntil.Value.ToUniversalTime().Ticks;
                workflow.NextExecution = Math.Min(pointerSleep, workflow.NextExecution ?? pointerSleep);
            }

            foreach (var pointer in workflow.ExecutionPointers.Where(x => x.Active && (x.Children ?? new List <string>()).Count > 0))
            {
                if (!workflow.ExecutionPointers.FindByScope(pointer.Id).All(x => x.EndTime.HasValue))
                {
                    continue;
                }

                if (!pointer.SleepUntil.HasValue)
                {
                    workflow.NextExecution = 0;
                    return;
                }

                var pointerSleep = pointer.SleepUntil.Value.ToUniversalTime().Ticks;
                workflow.NextExecution = Math.Min(pointerSleep, workflow.NextExecution ?? pointerSleep);
            }

            if ((workflow.NextExecution != null) || (workflow.ExecutionPointers.Any(x => x.EndTime == null)))
            {
                return;
            }

            workflow.Status       = WorkflowStatus.Complete;
            workflow.CompleteTime = _datetimeProvider.UtcNow;

            using (var scope = _serviceProvider.CreateScope())
            {
                var middlewareRunner = scope.ServiceProvider.GetRequiredService <IWorkflowMiddlewareRunner>();
                await middlewareRunner.RunPostMiddleware(workflow, def);
            }

            _publisher.PublishNotification(new WorkflowCompleted
            {
                EventTimeUtc         = _datetimeProvider.UtcNow,
                Reference            = workflow.Reference,
                WorkflowInstanceId   = workflow.Id,
                WorkflowDefinitionId = workflow.WorkflowDefinitionId,
                Version = workflow.Version
            });
        }
Esempio n. 36
0
 public async Task <string> CreateNewWorkflow(WorkflowInstance workflow)
 {
     workflow.Id = Guid.NewGuid().ToString();
     _instances.Add(workflow);
     return(workflow.Id);
 }
Esempio n. 37
0
        private void saveCodeActivity_ExecuteCode(object sender, EventArgs e)
        {
            var updateTreeRefresher = CreateUpdateTreeRefresher(EntityToken);

            var selectedPage = GetBinding <IPage>("SelectedPage");
            var originalPage = DataFacade.GetData <IPage>(f => f.Id == selectedPage.Id).SingleOrDefault();

            var viewLabelUpdated = originalPage == null ||
                                   selectedPage.MenuTitle != originalPage.MenuTitle ||
                                   selectedPage.Title != originalPage.Title;

            var treeviewRequiresRefreshing = false;

            var dataToAdd    = new Dictionary <string, IData>();
            var dataToUpdate = new Dictionary <string, IData>();

            var dataValidated = true;

            WorkflowInstance publishWorkflowInstance   = null;
            WorkflowInstance unpublishWorkflowInstance = null;

            try
            {
                using (var transactionScope = TransactionsFacade.CreateNewScope())
                {
                    dataValidated = PrepareAddUpdateMetaData(selectedPage, dataToAdd, dataToUpdate);

                    if (dataValidated)
                    {
                        PublishControlledHelper.HandlePublishUnpublishWorkflows(selectedPage, UserSettings.ActiveLocaleCultureInfo.Name, PublishDate, UnpublishDate, ref publishWorkflowInstance, ref unpublishWorkflowInstance);

                        if (selectedPage.PageTypeId != originalPage.PageTypeId)
                        {
                            // Adding metadata fields
                            var oldPageMetaDataDefinitions = originalPage.GetAllowedMetaDataDefinitions().Except(selectedPage.GetAllowedMetaDataDefinitions(), new PageMetaDataDefinitionEqualityComparer());

                            foreach (var pageMetaDataDefinition in oldPageMetaDataDefinitions)
                            {
                                var oldMetaData = selectedPage.GetMetaData(pageMetaDataDefinition.Name, pageMetaDataDefinition.MetaDataTypeId);
                                if (oldMetaData != null)
                                {
                                    ProcessControllerFacade.FullDelete(oldMetaData);
                                }
                            }


                            // Adding page folders
                            var pageTypeDataFolderTypeLinks =
                                DataFacade.GetData <IPageTypeDataFolderTypeLink>().
                                Where(f => f.PageTypeId == selectedPage.PageTypeId).
                                Evaluate().
                                RemoveDeadLinks();

                            foreach (var pageTypeDataFolderTypeLink in pageTypeDataFolderTypeLinks)
                            {
                                if (selectedPage.GetFolderDefinitionId(pageTypeDataFolderTypeLink.DataTypeId) != Guid.Empty)
                                {
                                    continue;
                                }

                                selectedPage.AddFolderDefinition(pageTypeDataFolderTypeLink.DataTypeId);
                                treeviewRequiresRefreshing = true;
                            }



                            // Adding applications
                            var pageTypeTreeLinks =
                                DataFacade.GetData <IPageTypeTreeLink>().
                                Where(f => f.PageTypeId == selectedPage.PageTypeId).
                                Evaluate().
                                RemoveDeadLinks();

                            foreach (var pageTypeTreeLink in pageTypeTreeLinks)
                            {
                                var tree = TreeFacade.GetTree(pageTypeTreeLink.TreeId);
                                if (tree.HasAttachmentPoints(selectedPage.GetDataEntityToken()))
                                {
                                    continue;
                                }

                                TreeFacade.AddPersistedAttachmentPoint(pageTypeTreeLink.TreeId, typeof(IPage), selectedPage.Id);
                                treeviewRequiresRefreshing = true;
                            }
                        }


                        foreach (var data in dataToAdd.Values)
                        {
                            DataFacade.AddNew(data);
                        }

                        foreach (var data in dataToUpdate.Values)
                        {
                            var publishControlled = data as IPublishControlled;
                            publishControlled.PublicationStatus = GenericPublishProcessController.Draft;

                            DataFacade.Update(data);
                        }

                        treeviewRequiresRefreshing |= (originalPage.Title != selectedPage.Title) ||
                                                      (originalPage.Description != selectedPage.Description) ||
                                                      (originalPage.PublicationStatus != selectedPage.PublicationStatus);

                        // NOTE: updating originalPage object, in order to make XML & SQL provider work in the same way
                        originalPage.TemplateId        = selectedPage.TemplateId;
                        originalPage.PageTypeId        = selectedPage.PageTypeId;
                        originalPage.Title             = selectedPage.Title;
                        originalPage.MenuTitle         = selectedPage.MenuTitle;
                        originalPage.UrlTitle          = selectedPage.UrlTitle;
                        originalPage.FriendlyUrl       = selectedPage.FriendlyUrl;
                        originalPage.Description       = selectedPage.Description;
                        originalPage.PublicationStatus = selectedPage.PublicationStatus;
                        originalPage.SourceCultureName = selectedPage.SourceCultureName;
                        DataFacade.Update(originalPage);

                        var contentDictionary = GetBinding <Dictionary <string, string> >("NamedXhtmlFragments");
                        var existingContents  = DataFacade.GetData <IPagePlaceholderContent>(f => f.PageId == selectedPage.Id).ToList();

                        foreach (var existingContent in existingContents)
                        {
                            if (contentDictionary.ContainsKey(existingContent.PlaceHolderId))
                            {
                                existingContent.Content           = contentDictionary[existingContent.PlaceHolderId];
                                existingContent.PublicationStatus = GenericPublishProcessController.Draft;
                                DataFacade.Update(existingContent);
                            }
                            else
                            {
                                DataFacade.Delete(existingContent);
                            }
                        }

                        foreach (var contentDictionaryElement in contentDictionary.Where(f => existingContents.Any(existing => existing.PlaceHolderId == f.Key) == false))
                        {
                            var newContent = DataFacade.BuildNew <IPagePlaceholderContent>();
                            newContent.PageId            = selectedPage.Id;
                            newContent.PlaceHolderId     = contentDictionaryElement.Key;
                            newContent.Content           = contentDictionaryElement.Value;
                            newContent.SourceCultureName = UserSettings.ActiveLocaleCultureInfo.Name;
                            newContent.PublicationStatus = GenericPublishProcessController.Draft;

                            DataFacade.AddNew(newContent);
                        }
                    }

                    transactionScope.Complete();
                }

                if (publishWorkflowInstance != null)
                {
                    publishWorkflowInstance.Start();
                    WorkflowFacade.RunWorkflow(publishWorkflowInstance);
                }

                if (unpublishWorkflowInstance != null)
                {
                    unpublishWorkflowInstance.Start();
                    WorkflowFacade.RunWorkflow(unpublishWorkflowInstance);
                }

                if (_doPublish)
                {
                    if (publishWorkflowInstance == null || PublishDate < DateTime.Now)
                    {
                        var actionToken = new GenericPublishProcessController.PublishActionToken();

                        var serviceContainer = WorkflowFacade.GetFlowControllerServicesContainer(WorkflowEnvironment.WorkflowInstanceId);

                        ActionExecutorFacade.Execute(EntityToken, actionToken, serviceContainer);

                        treeviewRequiresRefreshing = false;
                    }
                    else
                    {
                        var title   = StringResourceSystemFacade.GetString("Composite.Management", "Website.Forms.Administrative.EditPage.PublishDatePreventPublishTitle");
                        var message = StringResourceSystemFacade.GetString("Composite.Management", "Website.Forms.Administrative.EditPage.PublishDatePreventPublish");
                        ShowMessage(DialogType.Warning, title, message);
                    }
                }

                if (treeviewRequiresRefreshing)
                {
                    updateTreeRefresher.PostRefreshMesseges(selectedPage.GetDataEntityToken());
                }

                UpdateBinding("OldPublicationStatus", selectedPage.PublicationStatus);

                if (viewLabelUpdated)
                {
                    RerenderView();
                }
            }
            catch (Exception ex)
            {
                var mostSpecificException = ex;
                while (mostSpecificException.InnerException != null)
                {
                    mostSpecificException = mostSpecificException.InnerException;
                }
                ShowMessage(DialogType.Error, "Save failed", string.Format("Save failed: {0}", mostSpecificException.Message));
                Log.LogError("Page save", ex);
            }
            finally
            {
                SetSaveStatus(dataValidated);
            }
        }
        public void GetWorkflowInstances_should_retrieve_workflows()
        {
            var workflow01 = new WorkflowInstance()
            {
                Data = new TestData()
                {
                    Value1 = 7
                },
                Description          = "My Description",
                Status               = WorkflowStatus.Runnable,
                NextExecution        = 0,
                Version              = 1,
                WorkflowDefinitionId = "My Workflow",
                Reference            = "My Reference"
            };
            var executionPointerId1 = Guid.NewGuid().ToString();

            workflow01.ExecutionPointers.Add(new ExecutionPointer()
            {
                Id         = executionPointerId1,
                Active     = true,
                StepId     = 0,
                SleepUntil = new DateTime(2000, 1, 1).ToUniversalTime(),
                Scope      = new List <string>()
                {
                    "4", "3", "2", "1"
                }
            });
            var workflowId01 = Subject.CreateNewWorkflow(workflow01).Result;

            var workflow02 = new WorkflowInstance()
            {
                Data = new TestData()
                {
                    Value1 = 7
                },
                Description          = "My Description",
                Status               = WorkflowStatus.Runnable,
                NextExecution        = 0,
                Version              = 1,
                WorkflowDefinitionId = "My Workflow",
                Reference            = "My Reference"
            };
            var executionPointerId2 = Guid.NewGuid().ToString();

            workflow02.ExecutionPointers.Add(new ExecutionPointer()
            {
                Id         = executionPointerId2,
                Active     = true,
                StepId     = 0,
                SleepUntil = new DateTime(2000, 1, 1).ToUniversalTime(),
                Scope      = new List <string>()
                {
                    "4", "3", "2", "1"
                }
            });
            var workflowId02 = Subject.CreateNewWorkflow(workflow02).Result;

            var workflow03 = new WorkflowInstance()
            {
                Data = new TestData()
                {
                    Value1 = 7
                },
                Description          = "My Description",
                Status               = WorkflowStatus.Runnable,
                NextExecution        = 0,
                Version              = 1,
                WorkflowDefinitionId = "My Workflow",
                Reference            = "My Reference"
            };
            var executionPointerId3 = Guid.NewGuid().ToString();

            workflow03.ExecutionPointers.Add(new ExecutionPointer()
            {
                Id         = executionPointerId3,
                Active     = true,
                StepId     = 0,
                SleepUntil = new DateTime(2000, 1, 1).ToUniversalTime(),
                Scope      = new List <string>()
                {
                    "4", "3", "2", "1"
                }
            });
            var workflowId03 = Subject.CreateNewWorkflow(workflow03).Result;

            var retrievedWorkflows = Subject.GetWorkflowInstances(new[] { workflowId01, workflowId02, workflowId03 }).Result;

            retrievedWorkflows.Count().ShouldBeEquivalentTo(3);

            var retrievedWorkflow01 = retrievedWorkflows.Single(o => o.Id == workflowId01);

            retrievedWorkflow01.ShouldBeEquivalentTo(workflow01);
            retrievedWorkflow01.ExecutionPointers.FindById(executionPointerId1)
            .Scope.Should().ContainInOrder(workflow01.ExecutionPointers.FindById(executionPointerId1).Scope);

            var retrievedWorkflow02 = retrievedWorkflows.Single(o => o.Id == workflowId02);

            retrievedWorkflow02.ShouldBeEquivalentTo(workflow02);
            retrievedWorkflow02.ExecutionPointers.FindById(executionPointerId2)
            .Scope.Should().ContainInOrder(workflow02.ExecutionPointers.FindById(executionPointerId2).Scope);

            var retrievedWorkflow03 = retrievedWorkflows.Single(o => o.Id == workflowId03);

            retrievedWorkflow03.ShouldBeEquivalentTo(workflow03);
            retrievedWorkflow03.ExecutionPointers.FindById(executionPointerId3)
            .Scope.Should().ContainInOrder(workflow03.ExecutionPointers.FindById(executionPointerId3).Scope);
        }
 internal WorkflowInstanceProxy(WorkflowInstance instance)
 {
     this.instance = instance;
 }
Esempio n. 40
0
 private void RunWorkflow(WorkflowInstance workflow)
 {
     _scheduler.RunWorkflow(workflow.InstanceId);
 }
Esempio n. 41
0
        /// <summary>
        /// 计算环节参与人
        /// </summary>
        public override IEnumerable<IUser> Resolve(WorkflowInstance instance)
        {
            // 已当前环节的原处理人为计算基准
            var currentUser = SecurityContext.Provider.Get(instance.CurrentWorkItem.PartId);

            var actorUsers = new List<IUser>();

            // 优先级顺序
            // 1、指定环节处理人
            // 2、固定角色处理人(建单用户、系统)
            // 3、流程角色处理人(根据角色名称查询)
            // 4、基于场景(RoleBase:当前用户、建单用户)的角色处理人
            // 5、基于场景的指定部门的角色处理人

            // 指定环节处理人(获取该环节最后一次非AutoFinished的处理人)
            if (!string.IsNullOrEmpty(this.RefActivityName)) {
                var lastUser = GetLastActivityApprover(instance.InstanceNo, this.RefActivityName);
                if (lastUser != null) {
                    actorUsers.Add(lastUser);
                }
                return actorUsers;
            }

            // 固定角色
            if (string.IsNullOrEmpty(this.RoleName)) {
                throw new NullReferenceException("当前环节未配置有效的参与者计算规则");
            }

            if (this.RoleName == "建单用户") {
                actorUsers.Add(SecurityContext.Provider.Get(instance.CreatorId));
                return actorUsers;
            } else if (this.RoleName == "系统") {
                actorUsers.Add(SecurityContext.Provider.GetUser("system"));
                return actorUsers;
            } else {
                // 配置角色
                // 全局角色
                if (string.IsNullOrEmpty(this.RoleBase)) {
                    var roleUsers = _dao.QueryEntities<User>("k2client.actor.getroleusers", new { RoleName = this.RoleName });
                    actorUsers.AddRange(roleUsers.Select(roleUser => SecurityContext.Provider.Get(roleUser.Id)));
                    return actorUsers;
                } else if (this.RoleBase == "当前用户" || this.RoleBase == "建单用户") {
                    IList<User> listUser;

                    #region 逐层遍历
                    var tempOrgId = "";
                    switch (this.RoleBase) {
                        case "当前用户":
                            tempOrgId = currentUser.DeptId;
                            break;
                        case "建单用户":
                            tempOrgId = instance.CreatorDeptId;
                            break;
                    }

                    do {
                        listUser = _dao.QueryEntities<User>("K2Client.User.GetListByRoleOrg", new { OrgId = tempOrgId, RoleName = this.RoleName });
                        if (listUser == null || listUser.Count == 0) {
                            tempOrgId = _dao.QueryScalar<string>("K2Client.Organization.GetParentId", new { OrgId = tempOrgId });
                        }
                    } while ((listUser == null || listUser.Count == 0) && !string.IsNullOrEmpty(tempOrgId)); //这个遍历是逐部门往上的

                    #endregion

                    return listUser;
                } else if(this.RoleBase == "指定部门" && !string.IsNullOrEmpty(this.DeptId)) {
                    var listUser = _dao.QueryEntities<User>("K2Client.User.GetListByRoleOrg"
                        , new { OrgId = this.DeptId, RoleName = this.RoleName });

                    return listUser;
                }
            }

            return actorUsers;
        }
Esempio n. 42
0
 /// <summary>
 /// 是否可以查看流程
 /// </summary>
 public abstract bool CanViewWorkflow(WorkflowInstance instance);
        public void IsLoadedFiresPropertyChanged()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);
                var wi = new WorkflowInstance(model);
                var propChanged = false;

                wi.PropertyChanged += (sender, args) =>
                    {
                        if (!propChanged)
                        {
                            propChanged = args.PropertyName == "IsLoaded";
                        }
                    };

                // Act
                wi.New();

                // Assert
                Assert.IsTrue(propChanged);
            }
        }
Esempio n. 44
0
 internal void SetWorkflowInstance(WorkflowInstance workflowInstance)
 {
     CodeContract.Requires(workflowInstance != null);
     _workflowInstance = workflowInstance;
 }
        public void ResumeShouldResume()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);
                var wi = new WorkflowInstance(model);
                wi.New();

                // Act
                wi.Resume(StateTrigger.T1);

                // Assert
                Assert.AreEqual(StateMachineExample.State2, wi.StateTracker.CurrentState);
            }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            switch (this.RequestActionString.ToLower())
            {
            case "getusers":
                GetNextUsers(this.RequestData["TemplateId"].ToString(), this.RequestData["FlowInstanceId"].ToString(), this.RequestData["Name"].ToString(), this.RequestData["CurrentName"].ToString());
                break;

            case "getbackusers":
                Aim.WorkFlow.Task[] tks = Aim.WorkFlow.Task.FindAllByProperties(Aim.WorkFlow.Task.Prop_WorkflowInstanceID, this.RequestData["FlowInstanceId"].ToString(), Aim.WorkFlow.Task.Prop_ApprovalNodeName, this.RequestData["TaskName"].ToString());
                if (tks != null && tks.Length == 1)    //打回情况一个人的时候有效,多人的话,还是从之前配置里取
                {
                    this.PageState.Add("NextUserIds", tks[0].OwnerId);
                    this.PageState.Add("NextUserNames", tks[0].Owner);
                }
                break;

            default:
                Aim.WorkFlow.Task fTask = null;
                if (this.RequestData["FormId"] != null)
                {
                    Aim.WorkFlow.WorkflowInstance wf = WorkflowInstance.FindAllByProperties(WorkflowInstance.Prop_RelateId, this.RequestData["FormId"].ToString())[0];
                    fTask = Aim.WorkFlow.Task.FindAllByProperties(Aim.WorkFlow.Task.Prop_WorkflowInstanceID, wf.ID).Where(Ent => Ent.Ext1 != "Branch").ToArray()[0];
                }
                else
                {
                    fTask = Aim.WorkFlow.Task.Find(this.RequestData["TaskId"].ToString());
                }

                /*if (fTask.Ext1 == "Branch")
                 * {
                 *  Response.Redirect("FreeTask.aspx?op=r&Type=Branch&TaskId=" + this.RequestData["TaskId"].ToString());
                 * }*/
                /*if (!fTask.UpdatedTime.HasValue)
                 * {
                 *  try
                 *  {
                 *      DataTable dt = DataHelper.QueryDataTable("select FactDeptName,FactDeptId from View_SysUserGroupFact where UserId='" + this.UserInfo.UserID + "' and FactDeptName is not null ");
                 *      if (dt.Rows.Count > 0)
                 *      {
                 *          fTask.DeptId = dt.Rows[0]["FactDeptId"].ToString();
                 *          fTask.DeptName = dt.Rows[0]["FactDeptName"].ToString();
                 *      }
                 *  }
                 *  catch { }
                 *  fTask.UpdatedTime = DateTime.Now;
                 *  fTask.Save();
                 * }*/
                Aim.WorkFlow.WorkflowInstance instance = WorkflowInstance.Find(fTask.WorkflowInstanceID);
                this.PageState.Add("InstanceId", fTask.WorkflowInstanceID);
                this.PageState.Add("TemplateId", instance.WorkflowTemplateID);
                FlowInstanceId = instance.ID;
                FormUrl        = instance.RelateUrl;
                FlowDefineId   = instance.WorkflowTemplateID;
                Title          = fTask.WorkFlowName;//+ "->" + fTask.ApprovalNodeName;
                XmlSerializer xs = new XmlSerializer(typeof(TaskContext));
                if (!string.IsNullOrEmpty(fTask.Context))
                {
                    StringReader sr      = new StringReader(fTask.Context);
                    TaskContext  content = xs.Deserialize(sr) as TaskContext;
                    if (content.SwitchRules.Length > 0)
                    {
                        TaskContextSwitchRuleNextAction[] arrs = content.SwitchRules[0].NextActions;
                        string comboxdataText = "['{0}','{1}'],";
                        if (arrs.Length > 0)
                        {
                            int first = 0;
                            foreach (TaskContextSwitchRuleNextAction ar in arrs)
                            {
                                //GetNextRoute(currentNode, nsmgr, ar.Name)
                                NextStep += string.Format(comboxdataText, ar.Name, ar.Name);
                                if (first == 0)
                                {
                                    GetNextUsers(instance.WorkflowTemplateID, fTask.WorkflowInstanceID, ar.Name, fTask.ApprovalNodeName);
                                }
                                first++;
                            }
                        }
                        else
                        {
                            NextStep += string.Format("['','{0}'],", "结束");
                        }
                    }
                    else
                    {
                        NextStep += string.Format("['','{0}'],", "结束");
                    }
                }
                else
                {
                    NextStep += string.Format("['','{0}'],", "结束");
                }
                NextStep = NextStep.TrimEnd(',');
                Aim.WorkFlow.Task[] tasks = Aim.WorkFlow.Task.FindAll(Expression.Eq("WorkflowInstanceID", fTask.WorkflowInstanceID)).OrderBy(ens => !ens.FinishTime.HasValue ? DateTime.Now : ens.FinishTime).OrderBy(ens => ens.CreatedTime).ToArray();
                this.PageState.Add("Tasks", JsonHelper.GetJsonString(tasks));
                this.PageState.Add("Task", fTask);
                break;
            }
        }
Esempio n. 47
0
        private async Task ExecuteAsync(WorkflowInstance wfi, CancellationToken stoppingToken)
        {
            using var scope = _serviceProvider.CreateScope();
            var context = new StepExecutionContext()
            {
                StoppingToken   = stoppingToken,
                ServiceProvider = _serviceProvider,
                Logger          = _logger,
                ContextData     = wfi.Data
            };
            var executionResult = new ExecutionResult();
            var sw = new Stopwatch();

            try
            {
                _options?.Start?.Invoke(scope.ServiceProvider, wfi);
                var steps = scope.ServiceProvider.GetServices <IStepBodyAsync>().ToList();
                _logger.LogInformation($"{wfi.Id} Begin");
                sw.Start();
                if (!steps.Any())
                {
                    throw new WorkflowStepNotRegisteredException(wfi.WorkflowId, wfi.Version);
                }
                foreach (var workFlowStep in wfi.Steps)
                {
                    var retryCnt = 0;
                    context.CurrentStep = workFlowStep;
                    var stepBody = steps.FirstOrDefault(m => m.GetType() == workFlowStep.StepType);
                    if (stepBody == null)
                    {
                        throw new NullReferenceException(workFlowStep?.StepType?.FullName);
                    }
                    _logger.LogInformation($"{workFlowStep.Id}, Begin");
                    var inComeData = context.ContextData;
                    // retry step when fail
                    while (retryCnt++ <= Math.Abs(context.CurrentStep.FailedRetryCount))
                    {
                        executionResult = await stepBody.RunAsync(context, stoppingToken);

                        if (executionResult.Proceed)
                        {
                            break;
                        }
                    }

                    var outComeData = context.ContextData;
                    // persistent current step data & status
                    await _persistenceProvider.PersistWorkflowStepAsync(wfi.Id, wfi.WorkflowId, workFlowStep, inComeData, outComeData, executionResult, stoppingToken);

                    if (!executionResult.Proceed)
                    {
                        _logger.LogError(
                            $"{workFlowStep.Id}, retryCount: {retryCnt - 1}, error:{executionResult.InnerException.Message}");
                        break;
                    }

                    _logger.LogInformation($"{workFlowStep.Id}, End");
                    _logger.LogInformation(
                        $"{workFlowStep.Id}, {executionResult.ConsumeElapsedMilliseconds} ms");
                }

                sw.Stop();
                if (!executionResult.Proceed)
                {
                    _logger.LogError($"{wfi.Id}, End With Exception: {executionResult.InnerException}");
                }
                _logger.LogInformation($"{wfi.Id}, End and Execute: {sw.ElapsedMilliseconds} ms");
            }
            catch (System.Exception e)
            {
                _logger.LogError(e.Message, e);
                executionResult.Proceed        = false;
                executionResult.InnerException = e;
            }
            finally
            {
                await _persistenceProvider.PersistWorkflowInstanceAsync(wfi, context, executionResult, sw.ElapsedMilliseconds, stoppingToken);

                _options?.End?.Invoke(scope.ServiceProvider, wfi, context, executionResult);
            }
        }
Esempio n. 48
0
        public async Task <RunWorkflowResult> ReviveAndRunAsync(WorkflowInstance workflowInstance, CancellationToken cancellationToken)
        {
            workflowInstance = await ReviveAsync(workflowInstance, cancellationToken);

            return(await _resumesWorkflow.ResumeWorkflowAsync(workflowInstance, null, null, cancellationToken));
        }
Esempio n. 49
0
 /// <summary>
 /// 删除流程
 /// </summary>
 /// <param name="instance"></param>
 /// <returns></returns>
 public abstract bool DeleteWorkflow(WorkflowInstance instance);
 /// <summary>
 /// Constructor to initialize base class ProcessUow
 /// </summary>
 /// <param name="workflowInstance">WorkFlowInstance</param>
 /// <param name="unitOfWorkInstance">UnitOfWorkInstance</param>
 /// <param name="queue">Azure Queue</param>
 /// <param name="keepAlive">KeepAlive</param>
 /// <param name="container">Unity Container</param>
 public ClearStatisticsUow(
     WorkflowInstance workflowInstance, UnitOfWorkInstance unitOfWorkInstance,
     IQueue queue, Action keepAlive, IUnityContainer container) :
     base(workflowInstance, unitOfWorkInstance, queue, keepAlive, container)
 {
 }
Esempio n. 51
0
 /// <summary>
 /// 运行流程
 /// </summary>
 /// <param name="instance">流程编号</param>
 /// <param name="result">审批结果</param>
 /// <returns></returns>
 /// <remarks>
 /// 根据用户选择的下一步骤,计算出下一环节的参与者并持久化到数据库
 /// 1、检查流程数据的合法性(及权限)
 /// 2、根据Choice获取下一环节的定义(名称)
 /// 3、结束当前WorkflowItem
 /// 4、添加下一环节处理人的WorkItem(s)数据
 /// =========================================================
 /// 调用K2接口
 /// </remarks>
 public abstract bool RunWorkflow(WorkflowInstance instance, ApproveResult result);
Esempio n. 52
0
        /// <summary>
        /// 克隆一个实例
        /// </summary>
        /// <param name="WfRuntimeClone"></param>
        /// <param name="instanceClone"></param>
        /// <param name="WfRuntime"></param>
        /// <returns></returns>
        public static WorkflowInstance CloneWorkflowInstance(WorkflowRuntime WfRuntimeClone, WorkflowInstance instanceClone, WorkflowRuntime WfRuntime)
        {
            try
            {
                if (!WfRuntimeClone.IsStarted)
                {
                    WfRuntimeClone.StartRuntime();
                }
                StateMachineWorkflowInstance workflowinstance = new StateMachineWorkflowInstance(WfRuntimeClone, instanceClone.InstanceId);

                System.Workflow.Activities.StateMachineWorkflowActivity smworkflow = new StateMachineWorkflowActivity();
                smworkflow = workflowinstance.StateMachineWorkflow;
                RuleDefinitions          ruleDefinitions  = smworkflow.GetValue(RuleDefinitions.RuleDefinitionsProperty) as RuleDefinitions;
                WorkflowMarkupSerializer markupSerializer = new WorkflowMarkupSerializer();

                StringBuilder xoml       = new StringBuilder();
                StringBuilder rule       = new StringBuilder();
                XmlWriter     xmlWriter  = XmlWriter.Create(xoml);
                XmlWriter     ruleWriter = XmlWriter.Create(rule);
                markupSerializer.Serialize(xmlWriter, smworkflow);

                if (ruleDefinitions != null)
                {
                    markupSerializer.Serialize(ruleWriter, ruleDefinitions);
                }

                xmlWriter.Close();
                ruleWriter.Close();

                StringReader     readxoml   = new StringReader(xoml.ToString());
                XmlReader        readerxoml = XmlReader.Create(readxoml);
                WorkflowInstance instance;
                if (ruleDefinitions == null)
                {
                    instance = WfRuntime.CreateWorkflow(readerxoml);
                }
                else
                {
                    StringReader readrule   = new StringReader(rule.ToString());
                    XmlReader    readerrule = XmlReader.Create(readrule);
                    instance = WfRuntime.CreateWorkflow(readerxoml, readerrule, null);
                }

                instance.Start();
                return(instance);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("CloneWorkflowInstance异常信息 :" + ex.ToString());
                throw new Exception(ex.Message);
            }
        }
Esempio n. 53
0
 public DebugManager(Activity root, string moduleNamePrefix, string typeNamePrefix, string auxiliaryThreadName, bool breakOnStartup,
     WorkflowInstance host, bool debugStartedAtRoot) :
     this(root, moduleNamePrefix, typeNamePrefix, auxiliaryThreadName, breakOnStartup, host, debugStartedAtRoot, false)
 {
 }
Esempio n. 54
0
 /// <summary>
 /// 办理流程
 /// </summary>
 /// <param name="instance">流程实例</param>
 /// <param name="result">处理结果</param>
 /// <param name="listNextUsers">分配办理人员列表</param>
 /// <param name="tobeReadUsers">待阅人员</param>
 /// <remarks></remarks>
 /// <returns></returns>
 public abstract bool RunWorkflow(WorkflowInstance instance, ApproveResult result, IList<IUser> listNextUsers, IList<IUser> tobeReadUsers);
Esempio n. 55
0
 public WorkflowInstancePipeBind()
 {
     _instance = null;
     _id       = Guid.Empty;
 }
        public void UpgradeWorkflow(WorkflowRuntime runtime, Guid instanceId)
        {
            WorkflowInstance workflowInstance = runtime.GetWorkflow(instanceId);

            var definition = workflowInstance.GetWorkflowDefinition();

            if (!OldAssemblyNames.Contains(definition.GetType().Assembly.FullName))
            {
                return;
            }

            lock (GetLockForWorkflow(instanceId))
            {
                workflowInstance.Unload();

                var are = new AutoResetEvent(false);

                var parameters = new Dictionary <string, object>();

                //Получаем перзистанс и извлекаем состояние
                var persistance = runtime.GetService <NotTerminatingSqlWorkflowPersistenceService>();

                persistance.OnArgsAllowed +=
                    delegate(object sender, NotTerminatingSqlWorkflowPersistenceService.WorkflowSavedParametersArgs e)
                {
                    if (e.InstanceId == instanceId)
                    {
                        parameters = e.Parameters;
                        are.Set();
                    }
                };

                workflowInstance = runtime.GetWorkflow(instanceId);

                definition = workflowInstance.GetWorkflowDefinition();
                if (!OldAssemblyNames.Contains(definition.GetType().Assembly.FullName))
                {
                    //Если версия изменилась то дальнейшие манипуляции не нужны
                    return;
                }

                are.WaitOne(10000);

                workflowInstance.Unload();

                using (var context = this.CreateContext())
                {
                    context.DeleteWorkflowInPesistenceStore(instanceId);
                    context.SubmitChanges();
                }
                var workflowState = WorkflowStateService.GetWorkflowState(instanceId);

                parameters.Add(StateMachineWithSimpleContainer.DontWriteToWorkflowHistoryPersistenceKey, true);

                using (var sync = new WorkflowSync(runtime, instanceId))
                {
                    if (!CreateWorkflowIfNotExists(runtime, instanceId, workflowState.Type, parameters))
                    //Это ожидание создания воркфлоу
                    {
                        sync.WaitHandle.WaitOne(600000);
                    }
                }

                var wfinstance = new StateMachineWorkflowInstance(runtime, instanceId);
                using (var sync = new WorkflowSync(runtime, instanceId))
                //Это ожидание завершения установки состояния воркфлоу
                {
                    wfinstance.SetState(workflowState.WorkflowStateName);
                    sync.WaitHandle.WaitOne(600000);
                }

                var args = new SetWorkflowInternalParametersEventArgs(instanceId,
                                                                      new Dictionary <string, object>()
                {
                    {
                        StateMachineWithSimpleContainer.
                        DontWriteToWorkflowHistoryPersistenceKey
                        ,
                        false
                    }
                });
                SetInternalParameters(null, args);
            }
        }
Esempio n. 57
0
 /// <summary>
 /// 传阅流程
 /// </summary>
 /// <returns><c>true</c>, if around was passed, <c>false</c> otherwise.</returns>
 /// <param name="instance">流程实例.</param>
 /// <param name="toUsers">传阅用户.</param>
 public abstract bool PassAround(WorkflowInstance instance, IList<IUser> toUsers);
Esempio n. 58
0
 public WorkflowInstancePipeBind(WorkflowInstance instance)
 {
     _instance = instance;
 }
Esempio n. 59
0
 /// <summary>
 /// 启动流程实例
 /// </summary>
 /// <param name="instance">流程实例对象</param>
 /// <remarks>同时新增流程办理历史</remarks>
 /// <returns></returns>
 public abstract bool SaveWorkflow(WorkflowInstance instance);
Esempio n. 60
0
 public static async ValueTask UpdateInputAsync(this IWorkflowStorageService service, WorkflowInstance workflowInstance, WorkflowInput?workflowInput, CancellationToken cancellationToken = default)
 {
     if (workflowInput != null)
     {
         workflowInstance !.Input = await service.SaveAsync(workflowInput, workflowInstance, cancellationToken);
     }
 }