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 |
|||
{ |
|||
[DependsOn(typeof(AbpWorkflowCoreModule))] |
|||
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 |
|||
{ |
|||
public abstract class WorkflowBase : IWorkflow<WorkflowParamDictionary>, ISingletonDependency |
|||
public abstract class WorkflowBase : IWorkflow, ISingletonDependency |
|||
{ |
|||
public abstract string Id { 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.Collections.Generic; |
|||
using WorkflowCore.Models; |
|||
|
|||
namespace LINGYUN.Abp.WorkflowCore |
|||
{ |
|||
public class WorkflowStepBody |
|||
{ |
|||
public string Id { 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 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() |
|||
{ |
|||
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