35 changed files with 248 additions and 606 deletions
@ -1,51 +0,0 @@ |
|||||
using Microsoft.Extensions.Logging; |
|
||||
using System; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.EventBus.Distributed; |
|
||||
using WorkflowCore.Interface; |
|
||||
using EventData = WorkflowCore.Models.LifeCycleEvents.LifeCycleEvent; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore.LifeCycleEvent |
|
||||
{ |
|
||||
public class AbpEventBusLifeCycleEventHub : ILifeCycleEventHub |
|
||||
{ |
|
||||
private IDisposable _subscriber; |
|
||||
|
|
||||
private readonly IDistributedEventBus _eventBus; |
|
||||
private readonly ILoggerFactory _loggerFactory; |
|
||||
|
|
||||
public AbpEventBusLifeCycleEventHub( |
|
||||
ILoggerFactory loggerFactory, |
|
||||
IDistributedEventBus distributedEventBus) |
|
||||
{ |
|
||||
_loggerFactory = loggerFactory; |
|
||||
_eventBus = distributedEventBus; |
|
||||
} |
|
||||
|
|
||||
public async Task PublishNotification(EventData evt) |
|
||||
{ |
|
||||
await _eventBus.PublishAsync(evt); |
|
||||
} |
|
||||
|
|
||||
public Task Start() |
|
||||
{ |
|
||||
_subscriber = _eventBus.Subscribe(new LifeCycleEventHandler( |
|
||||
_loggerFactory.CreateLogger<LifeCycleEventHandler>())); |
|
||||
|
|
||||
return Task.CompletedTask; |
|
||||
} |
|
||||
|
|
||||
public Task Stop() |
|
||||
{ |
|
||||
// TODO
|
|
||||
_subscriber?.Dispose(); |
|
||||
|
|
||||
return Task.CompletedTask; |
|
||||
} |
|
||||
|
|
||||
public void Subscribe(Action<EventData> action) |
|
||||
{ |
|
||||
LifeCycleEventHandler.Subscribers.Add(action); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,86 @@ |
|||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Newtonsoft.Json; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.EventBus.Distributed; |
||||
|
using Volo.Abp.Json; |
||||
|
using WorkflowCore.Interface; |
||||
|
using EventData = WorkflowCore.Models.LifeCycleEvents.LifeCycleEvent; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WorkflowCore.LifeCycleEvent |
||||
|
{ |
||||
|
public class AbpEventBusProvider : ILifeCycleEventHub |
||||
|
{ |
||||
|
private bool _started = false; |
||||
|
private Queue<Action<EventData>> _deferredSubscribers = new Queue<Action<EventData>>(); |
||||
|
|
||||
|
private readonly IDistributedEventBus _eventBus; |
||||
|
private readonly ILoggerFactory _loggerFactory; |
||||
|
|
||||
|
private readonly JsonSerializerSettings _serializerSettings = new JsonSerializerSettings |
||||
|
{ |
||||
|
TypeNameHandling = TypeNameHandling.All, |
||||
|
ReferenceLoopHandling = ReferenceLoopHandling.Error, |
||||
|
}; |
||||
|
|
||||
|
public AbpEventBusProvider( |
||||
|
ILoggerFactory loggerFactory, |
||||
|
IDistributedEventBus distributedEventBus) |
||||
|
{ |
||||
|
_loggerFactory = loggerFactory; |
||||
|
_eventBus = distributedEventBus; |
||||
|
} |
||||
|
|
||||
|
public async Task PublishNotification(EventData evt) |
||||
|
{ |
||||
|
var data = evt.SerializeObject(_serializerSettings); |
||||
|
var wrapEvent = new LifeCycleEventWrap(data); |
||||
|
await _eventBus.PublishAsync(wrapEvent); |
||||
|
} |
||||
|
|
||||
|
public Task Start() |
||||
|
{ |
||||
|
_started = true; |
||||
|
while (_deferredSubscribers.Count > 0) |
||||
|
{ |
||||
|
var action = _deferredSubscribers.Dequeue(); |
||||
|
_eventBus.Subscribe<LifeCycleEventWrap>((data) => |
||||
|
{ |
||||
|
var unWrapData = data.Data.DeserializeObject(_serializerSettings); |
||||
|
action(unWrapData as EventData); |
||||
|
|
||||
|
return Task.CompletedTask; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
public Task Stop() |
||||
|
{ |
||||
|
// TODO
|
||||
|
_started = false; |
||||
|
|
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
public void Subscribe(Action<EventData> action) |
||||
|
{ |
||||
|
if (_started) |
||||
|
{ |
||||
|
_eventBus.Subscribe<LifeCycleEventWrap>((data) => |
||||
|
{ |
||||
|
var unWrapData = data.Data.DeserializeObject(_serializerSettings); |
||||
|
action(unWrapData as EventData); |
||||
|
|
||||
|
return Task.CompletedTask; |
||||
|
}); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
_deferredSubscribers.Enqueue(action); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,45 +0,0 @@ |
|||||
using Microsoft.Extensions.Logging; |
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.EventBus.Distributed; |
|
||||
using EventData = WorkflowCore.Models.LifeCycleEvents.LifeCycleEvent; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore.LifeCycleEvent |
|
||||
{ |
|
||||
public class LifeCycleEventHandler : IDistributedEventHandler<EventData> |
|
||||
{ |
|
||||
private readonly ILogger<LifeCycleEventHandler> _logger; |
|
||||
|
|
||||
internal static readonly ICollection<Action<EventData>> Subscribers = new HashSet<Action<EventData>>(); |
|
||||
|
|
||||
public LifeCycleEventHandler( |
|
||||
ILogger<LifeCycleEventHandler> logger) |
|
||||
{ |
|
||||
_logger = logger; |
|
||||
} |
|
||||
|
|
||||
public Task HandleEventAsync(EventData eventData) |
|
||||
{ |
|
||||
NotifySubscribers(eventData); |
|
||||
|
|
||||
return Task.CompletedTask; |
|
||||
} |
|
||||
|
|
||||
private void NotifySubscribers(EventData evt) |
|
||||
{ |
|
||||
foreach (var subscriber in Subscribers) |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
subscriber(evt); |
|
||||
} |
|
||||
catch (Exception ex) |
|
||||
{ |
|
||||
_logger.LogWarning( |
|
||||
default, ex, $"Error on event subscriber: {ex.Message}"); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,12 @@ |
|||||
|
namespace LINGYUN.Abp.WorkflowCore.LifeCycleEvent |
||||
|
{ |
||||
|
public class LifeCycleEventWrap |
||||
|
{ |
||||
|
public string Data { get; set; } |
||||
|
public LifeCycleEventWrap() { } |
||||
|
public LifeCycleEventWrap(string data) |
||||
|
{ |
||||
|
Data = data; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,47 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Collections.ObjectModel; |
|
||||
using Volo.Abp.Domain.Entities.Auditing; |
|
||||
using Volo.Abp.MultiTenancy; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore.Definitions |
|
||||
{ |
|
||||
public class WorkflowDefinition : FullAuditedAggregateRoot<Guid>, IMultiTenant |
|
||||
{ |
|
||||
public virtual Guid? TenantId { get; protected set; } |
|
||||
public string Title { get; protected set; } |
|
||||
public int Version { get; protected set; } |
|
||||
public string Description { get; protected set; } |
|
||||
public string Icon { get; protected set; } |
|
||||
public string Color { get; protected set; } |
|
||||
public string Group { get; protected set; } |
|
||||
public ICollection<WorkflowDefinitionNode> Nodes { get; protected set; } |
|
||||
public ICollection<WorkflowDefinitionFormData> Inputs { get; protected set; } |
|
||||
protected WorkflowDefinition() |
|
||||
{ |
|
||||
Nodes = new Collection<WorkflowDefinitionNode>(); |
|
||||
Inputs = new Collection<WorkflowDefinitionFormData>(); |
|
||||
} |
|
||||
public WorkflowDefinition( |
|
||||
Guid id, |
|
||||
string title, |
|
||||
int version, |
|
||||
string group, |
|
||||
string icon, |
|
||||
string color, |
|
||||
string description = null, |
|
||||
Guid? tenantId = null) : base(id) |
|
||||
{ |
|
||||
Title = title; |
|
||||
Version = version; |
|
||||
Group = group; |
|
||||
Icon = icon; |
|
||||
Color = color; |
|
||||
Description = description; |
|
||||
TenantId = tenantId; |
|
||||
|
|
||||
Nodes = new Collection<WorkflowDefinitionNode>(); |
|
||||
Inputs = new Collection<WorkflowDefinitionFormData>(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,30 +0,0 @@ |
|||||
using System; |
|
||||
using Volo.Abp.Domain.Entities; |
|
||||
using Volo.Abp.MultiTenancy; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore.Definitions |
|
||||
{ |
|
||||
public class WorkflowDefinitionConditionCondition : Entity<long>, IMultiTenant |
|
||||
{ |
|
||||
public virtual Guid? TenantId { get; protected set; } |
|
||||
public virtual Guid ParentId { get; protected set; } |
|
||||
public virtual WorkflowDefinitionConditionNode ConditionNode { get; protected set; } |
|
||||
public virtual string Field { get; set; } |
|
||||
public virtual string Operator { get; set; } |
|
||||
public virtual string Value { get; set; } |
|
||||
protected WorkflowDefinitionConditionCondition() { } |
|
||||
public WorkflowDefinitionConditionCondition( |
|
||||
Guid parentId, |
|
||||
string field, |
|
||||
string opt, |
|
||||
string value, |
|
||||
Guid? tenantId = null) |
|
||||
{ |
|
||||
ParentId = parentId; |
|
||||
Field = field; |
|
||||
Operator = opt; |
|
||||
Value = value; |
|
||||
TenantId = tenantId; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,37 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Collections.ObjectModel; |
|
||||
using Volo.Abp.Domain.Entities; |
|
||||
using Volo.Abp.MultiTenancy; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore.Definitions |
|
||||
{ |
|
||||
public class WorkflowDefinitionConditionNode : Entity<long>, IMultiTenant |
|
||||
{ |
|
||||
public virtual Guid? TenantId { get; protected set; } |
|
||||
public virtual Guid ParentId { get; protected set; } |
|
||||
public virtual WorkflowDefinitionNode Node { get; protected set; } |
|
||||
public virtual string Label { get; protected set; } |
|
||||
public virtual string NodeId { get; protected set; } |
|
||||
public virtual ICollection<WorkflowDefinitionConditionCondition> Conditions { get; protected set; } |
|
||||
|
|
||||
protected WorkflowDefinitionConditionNode() |
|
||||
{ |
|
||||
Conditions = new Collection<WorkflowDefinitionConditionCondition>(); |
|
||||
} |
|
||||
|
|
||||
public WorkflowDefinitionConditionNode( |
|
||||
Guid parentId, |
|
||||
string label, |
|
||||
string nodeId, |
|
||||
Guid? tenantId = null) |
|
||||
{ |
|
||||
ParentId = parentId; |
|
||||
Label = label; |
|
||||
NodeId = nodeId; |
|
||||
TenantId = tenantId; |
|
||||
|
|
||||
Conditions = new Collection<WorkflowDefinitionConditionCondition>(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,10 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Text; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore.Definitions |
|
||||
{ |
|
||||
public class WorkflowDefinitionExtensions |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -1,52 +0,0 @@ |
|||||
using System; |
|
||||
using Volo.Abp.Data; |
|
||||
using Volo.Abp.Domain.Entities; |
|
||||
using Volo.Abp.MultiTenancy; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore.Definitions |
|
||||
{ |
|
||||
public class WorkflowDefinitionFormData : Entity<long>, IMultiTenant |
|
||||
{ |
|
||||
public virtual Guid? TenantId { get; protected set; } |
|
||||
public virtual Guid WorkflowId { get; protected set; } |
|
||||
public virtual WorkflowDefinition Workflow { get; protected set; } |
|
||||
public virtual string Name { get; protected set; } |
|
||||
public virtual string Label { get; protected set; } |
|
||||
public virtual string Type { get; protected set; } |
|
||||
public virtual string Value { get; protected set; } |
|
||||
public virtual ExtraPropertyDictionary Styles { get; protected set; } |
|
||||
public virtual int? MaxLength { get; protected set; } |
|
||||
public virtual int? MinLength { get; protected set; } |
|
||||
public virtual ExtraPropertyDictionary Items { get; protected set; } |
|
||||
public virtual ExtraPropertyDictionary Rules { get; protected set; } |
|
||||
protected WorkflowDefinitionFormData() |
|
||||
{ |
|
||||
Styles = new ExtraPropertyDictionary(); |
|
||||
Items = new ExtraPropertyDictionary(); |
|
||||
Rules = new ExtraPropertyDictionary(); |
|
||||
} |
|
||||
public WorkflowDefinitionFormData( |
|
||||
Guid workflowId, |
|
||||
string name, |
|
||||
string label, |
|
||||
string type, |
|
||||
string value, |
|
||||
int? minLength = null, |
|
||||
int? maxLength = null, |
|
||||
Guid? tenantId = null) |
|
||||
{ |
|
||||
WorkflowId = workflowId; |
|
||||
Name = name; |
|
||||
Label = label; |
|
||||
Type = type; |
|
||||
Value = value; |
|
||||
MinLength = minLength; |
|
||||
MaxLength = maxLength; |
|
||||
TenantId = tenantId; |
|
||||
|
|
||||
Styles = new ExtraPropertyDictionary(); |
|
||||
Items = new ExtraPropertyDictionary(); |
|
||||
Rules = new ExtraPropertyDictionary(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,47 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Collections.ObjectModel; |
|
||||
using Volo.Abp.Domain.Entities; |
|
||||
using Volo.Abp.MultiTenancy; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore.Definitions |
|
||||
{ |
|
||||
public class WorkflowDefinitionNode : Entity<long>, IMultiTenant |
|
||||
{ |
|
||||
public virtual Guid? TenantId { get; protected set; } |
|
||||
public virtual Guid WorkflowId { get; protected set; } |
|
||||
public virtual WorkflowDefinition Workflow { get; protected set; } |
|
||||
public virtual string Key { get; protected set; } |
|
||||
public virtual string Title { get; protected set; } |
|
||||
public virtual string Position { get; protected set; } |
|
||||
public virtual string Type { get; protected set; } |
|
||||
public virtual WorkflowDefinitionStepBody StepBody { get; protected set; } |
|
||||
public virtual string ParentNodes { get; protected set; } |
|
||||
public virtual ICollection<WorkflowDefinitionConditionNode> NextNodes { get; protected set; } |
|
||||
protected WorkflowDefinitionNode() |
|
||||
{ |
|
||||
NextNodes = new Collection<WorkflowDefinitionConditionNode>(); |
|
||||
} |
|
||||
public WorkflowDefinitionNode( |
|
||||
Guid workflowId, |
|
||||
string key, |
|
||||
string title, |
|
||||
int[] position, |
|
||||
string type, |
|
||||
WorkflowDefinitionStepBody stepBody, |
|
||||
string[] parentNodes, |
|
||||
Guid? tenantId = null) |
|
||||
{ |
|
||||
WorkflowId = workflowId; |
|
||||
Key = key; |
|
||||
Title = title; |
|
||||
Position = position.JoinAsString(";"); |
|
||||
Type = type; |
|
||||
StepBody = stepBody; |
|
||||
ParentNodes = parentNodes.JoinAsString(";"); |
|
||||
TenantId = tenantId; |
|
||||
|
|
||||
NextNodes = new Collection<WorkflowDefinitionConditionNode>(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,28 +0,0 @@ |
|||||
using System; |
|
||||
using Volo.Abp.Data; |
|
||||
using Volo.Abp.Domain.Entities; |
|
||||
using Volo.Abp.MultiTenancy; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore.Definitions |
|
||||
{ |
|
||||
public class WorkflowDefinitionStepBody : Entity<Guid>, IMultiTenant, IHasExtraProperties |
|
||||
{ |
|
||||
public virtual Guid? TenantId { get; protected set; } |
|
||||
public virtual string Name { get; protected set; } |
|
||||
public ExtraPropertyDictionary ExtraProperties { get; protected set; } |
|
||||
protected WorkflowDefinitionStepBody() |
|
||||
{ |
|
||||
ExtraProperties = new ExtraPropertyDictionary(); |
|
||||
this.SetDefaultsForExtraProperties(); |
|
||||
} |
|
||||
public WorkflowDefinitionStepBody( |
|
||||
Guid id, |
|
||||
string name) : base(id) |
|
||||
{ |
|
||||
Name = name; |
|
||||
|
|
||||
ExtraProperties = new ExtraPropertyDictionary(); |
|
||||
this.SetDefaultsForExtraProperties(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,9 +1,22 @@ |
|||||
using Volo.Abp.Modularity; |
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using WorkflowCore.Interface; |
||||
|
using WorkflowCore.Models; |
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore.Persistence |
namespace LINGYUN.Abp.WorkflowCore.Persistence |
||||
{ |
{ |
||||
[DependsOn(typeof(AbpWorkflowCoreModule))] |
[DependsOn(typeof(AbpWorkflowCoreModule))] |
||||
public class AbpWorkflowCorePersistenceModule : AbpModule |
public class AbpWorkflowCorePersistenceModule : AbpModule |
||||
{ |
{ |
||||
|
public override void PreConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddSingleton<IPersistenceProvider, AbpWorkflowPersistenceProvider>(); |
||||
|
context.Services.AddSingleton<AbpWorkflowPersistenceProvider>(); |
||||
|
|
||||
|
PreConfigure<WorkflowOptions>(options => |
||||
|
{ |
||||
|
options.UsePersistence(provider => provider.GetRequiredService<AbpWorkflowPersistenceProvider>()); |
||||
|
}); |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -1,14 +1,14 @@ |
|||||
using WorkflowCore.Interface; |
using Volo.Abp.DependencyInjection; |
||||
using Volo.Abp.DependencyInjection; |
using WorkflowCore.Interface; |
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore |
namespace LINGYUN.Abp.WorkflowCore |
||||
{ |
{ |
||||
public abstract class WorkflowBase : IWorkflow<WorkflowParamDictionary>, ISingletonDependency |
public abstract class WorkflowBase : IWorkflow, ISingletonDependency |
||||
{ |
{ |
||||
public abstract string Id { get; } |
public abstract string Id { get; } |
||||
|
|
||||
public abstract int Version { get; } |
public abstract int Version { get; } |
||||
|
|
||||
public abstract void Build(IWorkflowBuilder<WorkflowParamDictionary> builder); |
public abstract void Build(IWorkflowBuilder<object> builder); |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -1,9 +0,0 @@ |
|||||
namespace LINGYUN.Abp.WorkflowCore |
|
||||
{ |
|
||||
public class WorkflowConditionCondition |
|
||||
{ |
|
||||
public string Field { get; set; } |
|
||||
public string Operator { get; set; } |
|
||||
public object Value { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,15 +0,0 @@ |
|||||
using System.Collections.Generic; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore |
|
||||
{ |
|
||||
public class WorkflowConditionNode |
|
||||
{ |
|
||||
public string Label { get; set; } |
|
||||
public string NodeId { get; set; } |
|
||||
public IEnumerable<WorkflowConditionCondition> Conditions { get; set; } |
|
||||
public WorkflowConditionNode() |
|
||||
{ |
|
||||
Conditions = new List<WorkflowConditionCondition>(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WorkflowCore |
||||
|
{ |
||||
|
public class WorkflowDefine |
||||
|
{ |
||||
|
public string Id { get; set; } |
||||
|
public int Version { get; set; } |
||||
|
public string Name { get; set; } |
||||
|
public Type DataType { get; set; } |
||||
|
public List<WorkflowStepBody> Steps { get; set; } |
||||
|
public WorkflowDefine() |
||||
|
{ |
||||
|
Steps = new List<WorkflowStepBody>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,17 +0,0 @@ |
|||||
using System.Collections.Generic; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore |
|
||||
{ |
|
||||
public class WorkflowDefinition |
|
||||
{ |
|
||||
public string Id { get; set; } |
|
||||
public string Title { get; set; } |
|
||||
public int Version { get; set; } |
|
||||
public string Description { get; set; } |
|
||||
public string Icon { get; set; } |
|
||||
public string Color { get; set; } |
|
||||
public string Group { get; set; } |
|
||||
public ICollection<WorkflowNode> Nodes { get; set; } |
|
||||
public ICollection<WorkflowFormData> Inputs { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,24 +0,0 @@ |
|||||
using System.Collections.Generic; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore |
|
||||
{ |
|
||||
public class WorkflowFormData |
|
||||
{ |
|
||||
public string Id { get; set; } |
|
||||
public string Name { get; set; } |
|
||||
public string Label { get; set; } |
|
||||
public string Type { get; set; } |
|
||||
public object Value { get; set; } |
|
||||
public IEnumerable<object> Styles { get; set; } |
|
||||
public int? MaxLength { get; set; } |
|
||||
public int? MinLength { get; set; } |
|
||||
public IEnumerable<object> Items { get; set; } |
|
||||
public IEnumerable<object> Rules { get; set; } |
|
||||
public WorkflowFormData() |
|
||||
{ |
|
||||
Styles = new List<object>(); |
|
||||
Items = new List<object>(); |
|
||||
Rules =new List<object>(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,105 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using Volo.Abp; |
|
||||
using WorkflowCore.Interface; |
|
||||
using WorkflowCore.Models.DefinitionStorage.v1; |
|
||||
using WorkflowCore.Services.DefinitionStorage; |
|
||||
using WDF = WorkflowCore.Models.WorkflowDefinition; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore |
|
||||
{ |
|
||||
public class WorkflowManager : IWorkflowManager |
|
||||
{ |
|
||||
private readonly IWorkflowRegistry _workflowRegistry; |
|
||||
private readonly IDefinitionLoader _definitionLoader; |
|
||||
|
|
||||
protected IReadOnlyCollection<WorkflowStepBody> _stepBodys; |
|
||||
|
|
||||
internal void Initlize() |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
|
|
||||
public WDF BuildWorkflow(WorkflowDefinition definition) |
|
||||
{ |
|
||||
if (_workflowRegistry.IsRegistered(definition.Id, definition.Version)) |
|
||||
{ |
|
||||
throw new AbpException($"Workflow {definition.Id} has ben registered!"); |
|
||||
} |
|
||||
|
|
||||
var definitionSource = new DefinitionSourceV1() |
|
||||
{ |
|
||||
Id = definition.Id, |
|
||||
Version = definition.Version, |
|
||||
DataType = $"{typeof(Dictionary<string, object>).FullName}, {typeof(Dictionary<string, object>).Assembly.FullName}", |
|
||||
Description = definition.Title, |
|
||||
}; |
|
||||
|
|
||||
BuildWorkflow(definition.Nodes, definitionSource, _stepBodys, definition.Nodes.First(u => u.Key.ToLower().StartsWith("start"))); |
|
||||
var json = definitionSource.SerializeObject(); |
|
||||
var def = _definitionLoader.LoadDefinition(json, Deserializers.Json); |
|
||||
return def; |
|
||||
} |
|
||||
|
|
||||
protected virtual void BuildWorkflow(IEnumerable<WorkflowNode> allNodes, DefinitionSourceV1 source, IEnumerable<WorkflowStepBody> stepBodys, WorkflowNode node) |
|
||||
{ |
|
||||
if (source.Steps.Any(u => u.Id == node.Key)) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
var stepSource = new StepSourceV1 |
|
||||
{ |
|
||||
Id = node.Key, |
|
||||
Name = node.Key |
|
||||
}; |
|
||||
WorkflowStepBody stepbody = stepBodys.FirstOrDefault(u => u.Name == node.StepBody.Name); |
|
||||
if (stepbody == null) |
|
||||
{ |
|
||||
stepbody = new WorkflowStepBody() { StepBodyType = typeof(NullStepBody) }; |
|
||||
} |
|
||||
stepSource.StepType = $"{stepbody.StepBodyType.FullName}, {stepbody.StepBodyType.Assembly.FullName}"; |
|
||||
|
|
||||
foreach (var input in stepbody.Inputs) |
|
||||
{ |
|
||||
var value = node.StepBody.Inputs[input.Key].Value; |
|
||||
if (!(value is IDictionary<string, object> || value is IDictionary<object, object>)) |
|
||||
{ |
|
||||
value = $"\"{value}\""; |
|
||||
} |
|
||||
stepSource.Inputs.AddIfNotContains(new KeyValuePair<string, object>(input.Key, value)); |
|
||||
} |
|
||||
source.Steps.Add(stepSource); |
|
||||
BuildBranching(allNodes, source, stepSource, stepBodys, node.NextNodes); |
|
||||
} |
|
||||
protected virtual void BuildBranching(IEnumerable<WorkflowNode> allNodes, DefinitionSourceV1 source, StepSourceV1 stepSource, IEnumerable<WorkflowStepBody> stepBodys, IEnumerable<WorkflowConditionNode> nodes) |
|
||||
{ |
|
||||
foreach (var nextNode in nodes) |
|
||||
{ |
|
||||
var node = allNodes.First(u => u.Key == nextNode.NodeId); |
|
||||
stepSource.SelectNextStep[nextNode.NodeId] = "1==1"; |
|
||||
if (nextNode.Conditions.Count() > 0) |
|
||||
{ |
|
||||
List<string> exps = new List<string>(); |
|
||||
foreach (var cond in nextNode.Conditions) |
|
||||
{ |
|
||||
if (cond.Value is string && (!decimal.TryParse(cond.Value.ToString(), out decimal tempValue))) |
|
||||
{ |
|
||||
if (cond.Operator != "==" && cond.Operator != "!=") |
|
||||
{ |
|
||||
throw new AbpException($" if {cond.Field} is type of 'String', the Operator must be \"==\" or \"!=\""); |
|
||||
} |
|
||||
exps.Add($"data[\"{cond.Field}\"].ToString() {cond.Operator} \"{cond.Value}\""); |
|
||||
continue; |
|
||||
} |
|
||||
exps.Add($"decimal.Parse(data[\"{cond.Field}\"].ToString()) {cond.Operator} {cond.Value}"); |
|
||||
} |
|
||||
stepSource.SelectNextStep[nextNode.NodeId] = string.Join(" && ", exps); |
|
||||
} |
|
||||
|
|
||||
BuildWorkflow(allNodes, source, stepBodys, node); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
using System.Collections.Generic; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore |
|
||||
{ |
|
||||
public class WorkflowNode |
|
||||
{ |
|
||||
public string Key { get; set; } |
|
||||
public string Title { get; set; } |
|
||||
public int[] Position { get; set; } |
|
||||
public string Type { get; set; } |
|
||||
public WorkflowStepBody StepBody { get; set; } |
|
||||
public IEnumerable<string> ParentNodes { get; set; } |
|
||||
public IEnumerable<WorkflowConditionNode> NextNodes { get; set; } |
|
||||
public WorkflowNode() |
|
||||
{ |
|
||||
StepBody = new WorkflowStepBody(); |
|
||||
NextNodes = new List<WorkflowConditionNode>(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,10 +0,0 @@ |
|||||
namespace LINGYUN.Abp.WorkflowCore |
|
||||
{ |
|
||||
public class WorkflowParam |
|
||||
{ |
|
||||
public string Name { get; set; } |
|
||||
public string DisplayName { get; set; } |
|
||||
public string InputType { get; set; } |
|
||||
public object Value { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,8 +0,0 @@ |
|||||
using System.Collections.Generic; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore |
|
||||
{ |
|
||||
public class WorkflowParamDictionary : Dictionary<string, WorkflowParam> |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -1,8 +0,0 @@ |
|||||
namespace LINGYUN.Abp.WorkflowCore |
|
||||
{ |
|
||||
public class WorkflowParamInput |
|
||||
{ |
|
||||
public string Name { get; set; } |
|
||||
public object Value { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,17 +1,31 @@ |
|||||
using System; |
using System; |
||||
using System.Collections.Generic; |
using System.Collections.Generic; |
||||
|
using WorkflowCore.Models; |
||||
|
|
||||
namespace LINGYUN.Abp.WorkflowCore |
namespace LINGYUN.Abp.WorkflowCore |
||||
{ |
{ |
||||
public class WorkflowStepBody |
public class WorkflowStepBody |
||||
{ |
{ |
||||
|
public string Id { get; set; } |
||||
public string Name { get; set; } |
public string Name { get; set; } |
||||
public Type StepBodyType { get; set; } |
public Type StepType { get; set; } |
||||
|
public bool Saga { get; set; } |
||||
public string DisplayName { get; set; } |
public string DisplayName { get; set; } |
||||
public Dictionary<string, WorkflowParamInput> Inputs { get; set; } |
public string NextStep { get; set; } |
||||
|
public string CancelCondition { get; set; } |
||||
|
public TimeSpan? RetryInterval { get; set; } |
||||
|
public WorkflowErrorHandling? ErrorBehavior { get; set; } |
||||
|
public List<WorkflowStepBody> CompensateWith { get; set; } |
||||
|
public Dictionary<string, object> Inputs { get; set; } |
||||
|
public Dictionary<string, object> Outputs { get; set; } |
||||
|
public Dictionary<string, object> SelectNextStep { get; set; } |
||||
|
|
||||
public WorkflowStepBody() |
public WorkflowStepBody() |
||||
{ |
{ |
||||
Inputs = new Dictionary<string, WorkflowParamInput>(); |
CompensateWith = new List<WorkflowStepBody>(); |
||||
|
Inputs = new Dictionary<string, object>(); |
||||
|
Outputs = new Dictionary<string, object>(); |
||||
|
SelectNextStep = new Dictionary<string, object>(); |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
Loading…
Reference in new issue