Browse Source

feat(workflow): 增加ES存储支持,增加工作流管理项目.

pull/432/head
cKey 4 years ago
parent
commit
325e8b8ddc
  1. 1
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Components/LINGYUN.Abp.WorkflowCore.Components.csproj
  2. 8
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Components/LINGYUN/Abp/WorkflowCore/Components/AbpWorkflowCoreComponentsModule.cs
  3. 81
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Components/LINGYUN/Abp/WorkflowCore/Components/Primitives/RemoteService.cs
  4. 8
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Components/LINGYUN/Abp/WorkflowCore/Components/Primitives/SendEmail.cs
  5. 8
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Components/LINGYUN/Abp/WorkflowCore/Components/Primitives/SendSms.cs
  6. 3
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Elasticsearch/LINGYUN/Abp/WorkflowCore/Elasticsearch/AbpElasticsearchIndexer.cs
  7. 20
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch/LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch.csproj
  8. 22
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch/LINGYUN/Abp/WorkflowCore/Persistence/Elasticsearch/AbpWorkflowCorePersistenceElasticsearchModule.cs
  9. 14
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch/LINGYUN/Abp/WorkflowCore/Persistence/Elasticsearch/AbpWorkflowCorePersistenceElasticsearchOptions.cs
  10. 555
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch/LINGYUN/Abp/WorkflowCore/Persistence/Elasticsearch/ElasticsearchPersistenceProvider.cs
  11. 32
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch/LINGYUN/Abp/WorkflowCore/Persistence/Elasticsearch/Models/PersistedScheduledCommand.cs
  12. 4
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence/LINGYUN/Abp/WorkflowCore/Persistence/AbpWorkflowCorePersistenceModule.cs
  13. 3
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence/LINGYUN/Abp/WorkflowCore/Persistence/AbpWorkflowPersistenceProvider.cs
  14. 6
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore/LINGYUN.Abp.WorkflowCore.csproj
  15. 22
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore/LINGYUN/Abp/WorkflowCore/AbpDateTimeProvider.cs
  16. 20
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application.Contracts/LINGYUN.Abp.WorkflowManagement.Application.Contracts.csproj
  17. 23
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application.Contracts/LINGYUN/Abp/WorkflowManagement/Authorization/WorkflowManagementPermissionDefinitionProvider.cs
  18. 9
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application.Contracts/LINGYUN/Abp/WorkflowManagement/Authorization/WorkflowManagementPermissions.cs
  19. 14
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application.Contracts/LINGYUN/Abp/WorkflowManagement/WorkflowManagementApplicationContractsModule.cs
  20. 7
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application.Contracts/LINGYUN/Abp/WorkflowManagement/WorkflowManagementRemoteServiceConsts.cs
  21. 20
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application/LINGYUN.Abp.WorkflowManagement.Application.csproj
  22. 14
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application/LINGYUN/Abp/WorkflowManagement/WorkflowManagementAppServiceBase.cs
  23. 11
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application/LINGYUN/Abp/WorkflowManagement/WorkflowManagementApplicationMapperProfile.cs
  24. 25
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application/LINGYUN/Abp/WorkflowManagement/WorkflowManagementApplicationModule.cs
  25. 27
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain.Shared/LINGYUN.Abp.WorkflowManagement.Domain.Shared.csproj
  26. 7
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain.Shared/LINGYUN/Abp/WorkflowManagement/Localization/Resources/en.json
  27. 7
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain.Shared/LINGYUN/Abp/WorkflowManagement/Localization/Resources/zh-Hans.json
  28. 9
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain.Shared/LINGYUN/Abp/WorkflowManagement/Localization/WorkflowManagementResource.cs
  29. 33
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain.Shared/LINGYUN/Abp/WorkflowManagement/WorkflowManagementDomainSharedModule.cs
  30. 7
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain.Shared/LINGYUN/Abp/WorkflowManagement/WorkflowManagementErrorCodes.cs
  31. 22
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN.Abp.WorkflowManagement.Domain.csproj
  32. 11
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/Settings/WorkflowManagementSettingDefinitionProvider.cs
  33. 7
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/Settings/WorkflowManagementSettings.cs
  34. 57
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/Step.cs
  35. 45
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/Workflow.cs
  36. 12
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/WorkflowManagementDbProperties.cs
  37. 12
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/WorkflowManagementDomainMapperProfile.cs
  38. 27
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/WorkflowManagementDomainModule.cs
  39. 19
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore.csproj
  40. 10
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore/LINGYUN/Abp/WorkflowManagement/EntityFrameworkCore/IWorkflowManagementDbContext.cs
  41. 20
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore/LINGYUN/Abp/WorkflowManagement/EntityFrameworkCore/WorkflowManagementDbContext.cs
  42. 22
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore/LINGYUN/Abp/WorkflowManagement/EntityFrameworkCore/WorkflowManagementDbContextModelCreatingExtensions.cs
  43. 20
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore/LINGYUN/Abp/WorkflowManagement/EntityFrameworkCore/WorkflowManagementEntityFrameworkCoreModule.cs
  44. 18
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore/LINGYUN/Abp/WorkflowManagement/EntityFrameworkCore/WorkflowManagementModelBuilderConfigurationOptions.cs
  45. 19
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.HttpApi/LINGYUN.Abp.WorkflowManagement.HttpApi.csproj
  46. 41
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.HttpApi/LINGYUN/Abp/WorkflowManagement/WorkflowManagementHttpApiModule.cs
  47. 20
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.SettingManagement/LINGYUN.Abp.WorkflowManagement.SettingManagement.csproj
  48. 77
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.SettingManagement/LINGYUN/Abp/WorkflowManagement/SettingManagement/SettingAppService.cs
  49. 48
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.SettingManagement/LINGYUN/Abp/WorkflowManagement/SettingManagement/SettingController.cs
  50. 15
      aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.SettingManagement/LINGYUN/Abp/WorkflowManagement/SettingManagement/WorkflowManagementSettingManagementModule.cs

1
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Components/LINGYUN.Abp.WorkflowCore.Components.csproj

@ -11,6 +11,7 @@
<ItemGroup>
<PackageReference Include="Volo.Abp.Emailing" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Sms" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Http.Client" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>

8
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Components/LINGYUN/Abp/WorkflowCore/Components/AbpWorkflowCoreComponentsModule.cs

@ -1,4 +1,6 @@
using Volo.Abp.Emailing;
using LINGYUN.Abp.WorkflowCore.Components.Authentication;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Emailing;
using Volo.Abp.Modularity;
using Volo.Abp.Sms;
@ -10,5 +12,9 @@ namespace LINGYUN.Abp.WorkflowCore.Components
typeof(AbpWorkflowCoreModule))]
public class AbpWorkflowCoreComponentsModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddSingleton<ICurrentAssigner>(AsyncLocalCurrentAssigner.Instance);
}
}
}

81
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Components/LINGYUN/Abp/WorkflowCore/Components/Primitives/RemoteService.cs

@ -0,0 +1,81 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
using WorkflowCore.Interface;
using WorkflowCore.Models;
namespace LINGYUN.Abp.WorkflowCore.Components.Primitives
{
public class RemoteService : StepBodyAsyncBase
{
private readonly ICurrentTenant _currentTenant;
private readonly IServiceProvider _serviceProvider;
public RemoteService(
ICurrentTenant currentTenant,
IServiceProvider serviceProvider)
{
_currentTenant = currentTenant;
_serviceProvider = serviceProvider;
Data = new Dictionary<string, object>();
}
/// <summary>
/// 远程服务接口类型
/// </summary>
public string Interface { get; set; }
/// <summary>
/// 远程服务方法名称
/// </summary>
public string Method { get; set; }
/// <summary>
/// 请求参数
/// </summary>
public Dictionary<string, object> Data { get; set; }
/// <summary>
/// 调用结果
/// </summary>
public object Result { get; set; }
public Guid? TenantId { get; set; }
public string CurrentCulture { get; set; }
public override async Task<ExecutionResult> RunAsync(IStepExecutionContext context)
{
var serviceType = Type.GetType(Interface, true, true);
var method = serviceType.GetMethod(Method);
var serviceFactory = _serviceProvider.GetRequiredService(serviceType);
using (_currentTenant.Change(TenantId))
{
using (CultureHelper.Use(CurrentCulture ?? CultureInfo.CurrentCulture.Name))
{
// TODO: 身份令牌?
// 工作流中是否需要调用API, 还是用户调用API之后传递事件激活下一个步骤
// Abp Api动态代理
var result = (Task)method.Invoke(serviceFactory, Data.Select(x => x.Value).ToArray());
await result;
if (!method.ReturnType.GenericTypeArguments.IsNullOrEmpty())
{
var resultType = method.ReturnType.GenericTypeArguments[0];
var resultProperty = typeof(Task<>)
.MakeGenericType(resultType)
.GetProperty(nameof(Task<object>.Result), BindingFlags.Instance | BindingFlags.Public);
Result = resultProperty.GetValue(result);
}
return ExecutionResult.Next();
}
}
}
}
}

8
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Components/LINGYUN/Abp/WorkflowCore/Components/Primitives/EmailStepBody.cs → aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Components/LINGYUN/Abp/WorkflowCore/Components/Primitives/SendEmail.cs

@ -12,21 +12,21 @@ using WorkflowCore.Models;
namespace LINGYUN.Abp.WorkflowCore.Components.Primitives
{
public class EmailStepBody : StepBodyAsyncBase
public class SendEmail : StepBodyAsyncBase
{
public ILogger<EmailStepBody> Logger { protected get; set; }
public ILogger<SendEmail> Logger { protected get; set; }
private readonly IEmailSender _emailSender;
private readonly ITemplateRenderer _templateRenderer;
public EmailStepBody(
public SendEmail(
IEmailSender emailSender,
ITemplateRenderer templateRenderer)
{
_emailSender = emailSender;
_templateRenderer = templateRenderer;
Logger = NullLogger<EmailStepBody>.Instance;
Logger = NullLogger<SendEmail>.Instance;
}
[NotNull]

8
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Components/LINGYUN/Abp/WorkflowCore/Components/Primitives/SmsStepBody.cs → aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Components/LINGYUN/Abp/WorkflowCore/Components/Primitives/SendSms.cs

@ -9,18 +9,18 @@ using WorkflowCore.Models;
namespace LINGYUN.Abp.WorkflowCore.Components.Primitives
{
public class SmsStepBody : StepBodyAsyncBase
public class SendSms : StepBodyAsyncBase
{
public ILogger<SmsStepBody> Logger { protected get; set; }
public ILogger<SendSms> Logger { protected get; set; }
private readonly ISmsSender _smsSender;
public SmsStepBody(ISmsSender smsSender)
public SendSms(ISmsSender smsSender)
{
_smsSender = smsSender;
Logger = NullLogger<SmsStepBody>.Instance;
Logger = NullLogger<SendSms>.Instance;
}
[NotNull]

3
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Elasticsearch/LINGYUN/Abp/WorkflowCore/Elasticsearch/AbpElasticsearchIndexer.cs

@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Volo.Abp;
using WorkflowCore.Interface;
using WorkflowCore.Models;
using WorkflowCore.Models.Search;
@ -46,7 +47,7 @@ namespace LINGYUN.Abp.WorkflowCore.Elasticsearch
if (!result.ApiCall.Success)
{
_logger.LogError(default(EventId), result.ApiCall.OriginalException, $"Failed to index workflow {workflow.Id}");
throw new ApplicationException($"Failed to index workflow {workflow.Id}", result.ApiCall.OriginalException);
throw new AbpException($"Failed to index workflow {workflow.Id}", result.ApiCall.OriginalException);
}
}

20
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch/LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Guids" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\elasticsearch\LINGYUN.Abp.Elasticsearch\LINGYUN.Abp.Elasticsearch.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.WorkflowCore\LINGYUN.Abp.WorkflowCore.csproj" />
</ItemGroup>
</Project>

22
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch/LINGYUN/Abp/WorkflowCore/Persistence/Elasticsearch/AbpWorkflowCorePersistenceElasticsearchModule.cs

@ -0,0 +1,22 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
using WorkflowCore.Interface;
using WorkflowCore.Models;
namespace LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch
{
[DependsOn(typeof(AbpWorkflowCoreModule))]
public class AbpWorkflowCorePersistenceElasticsearchModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient<IPersistenceProvider, ElasticsearchPersistenceProvider>();
context.Services.AddTransient<ElasticsearchPersistenceProvider>();
PreConfigure<WorkflowOptions>(options =>
{
options.UsePersistence(provider => provider.GetRequiredService<ElasticsearchPersistenceProvider>());
});
}
}
}

14
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch/LINGYUN/Abp/WorkflowCore/Persistence/Elasticsearch/AbpWorkflowCorePersistenceElasticsearchOptions.cs

@ -0,0 +1,14 @@
namespace LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch
{
public class AbpWorkflowCorePersistenceElasticsearchOptions
{
/// <summary>
/// Default Value: abp.workflows.persistence
/// </summary>
public string IndexFormat { get; set; }
public AbpWorkflowCorePersistenceElasticsearchOptions()
{
IndexFormat = "abp.workflows.persistence";
}
}
}

555
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch/LINGYUN/Abp/WorkflowCore/Persistence/Elasticsearch/ElasticsearchPersistenceProvider.cs

@ -0,0 +1,555 @@
using LINGYUN.Abp.Elasticsearch;
using LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Nest;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using WorkflowCore.Interface;
using WorkflowCore.Models;
namespace LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch
{
public class ElasticsearchPersistenceProvider : IPersistenceProvider, ITransientDependency
{
private readonly ILogger<ElasticsearchPersistenceProvider> _logger;
private readonly IGuidGenerator _guidGenerator;
private readonly IElasticsearchClientFactory _elasticsearchClientFactory;
private readonly AbpWorkflowCorePersistenceElasticsearchOptions _options;
public ElasticsearchPersistenceProvider(
IGuidGenerator guidGenerator,
IElasticsearchClientFactory elasticsearchClientFactory,
IOptions<AbpWorkflowCorePersistenceElasticsearchOptions> options,
ILogger<ElasticsearchPersistenceProvider> logger)
{
_guidGenerator = guidGenerator;
_elasticsearchClientFactory = elasticsearchClientFactory;
_options = options.Value;
_logger = logger;
}
public bool SupportsScheduledCommands => true;
public virtual async Task ClearSubscriptionToken(string eventSubscriptionId, string token, CancellationToken cancellationToken = default)
{
var id = Guid.Parse(eventSubscriptionId);
var client = CreateClient();
var response = await client.GetAsync<EventSubscription>(
id,
dsl => dsl.Index(CreateIndex()),
ct: cancellationToken);
CheckResponse(response);
if (response.Found)
{
if (response.Source.ExternalToken != token)
{
throw new InvalidOperationException();
}
response.Source.ExternalToken = null;
response.Source.ExternalWorkerId = null;
response.Source.ExternalTokenExpiry = null;
await client.UpdateAsync<EventSubscription>(
id,
dsl => dsl.Index(CreateIndex())
.Doc(response.Source),
ct: cancellationToken);
}
}
public virtual async Task<string> CreateEvent(Event newEvent, CancellationToken cancellationToken = default)
{
var client = CreateClient();
var newEventId = _guidGenerator.Create();
newEvent.Id = newEventId.ToString();
var response = await client.IndexAsync(
newEvent,
dsl => dsl.Index(CreateIndex())
.Id(newEventId),
ct: cancellationToken);
CheckResponse(response);
return newEvent.Id;
}
public virtual async Task<string> CreateEventSubscription(EventSubscription subscription, CancellationToken cancellationToken = default)
{
var client = CreateClient();
var newSubscriptionId = _guidGenerator.Create();
subscription.Id = newSubscriptionId.ToString();
var response = await client.IndexAsync(
subscription,
dsl => dsl.Index(CreateIndex())
.Id(newSubscriptionId),
ct: cancellationToken);
CheckResponse(response);
return subscription.Id;
}
public virtual async Task<string> CreateNewWorkflow(WorkflowInstance workflow, CancellationToken cancellationToken = default)
{
var client = CreateClient();
var newWorkflowId = _guidGenerator.Create();
workflow.Id = newWorkflowId.ToString();
var response = await client.IndexAsync(
workflow,
dsl => dsl.Index(CreateIndex())
.Id(newWorkflowId),
ct: cancellationToken);
CheckResponse(response);
return workflow.Id;
}
public void EnsureStoreExists()
{
// TODO: 为什么是同步API...
var client = CreateClient();
var response = client.Indices.Exists(CreateIndex());
if (!response.Exists)
{
client.Indices.Create(CreateIndex());
}
}
public virtual async Task<Event> GetEvent(string id, CancellationToken cancellationToken = default)
{
var eventId = Guid.Parse(id);
var client = CreateClient();
var response = await client.GetAsync<Event>(
eventId,
dsl => dsl.Index(CreateIndex()),
ct: cancellationToken);
CheckResponse(response);
return response.Source;
}
public virtual async Task<IEnumerable<string>> GetEvents(string eventName, string eventKey, DateTime asOf, CancellationToken cancellationToken = default)
{
var client = CreateClient();
var terms = new List<Func<QueryContainerDescriptor<Event>, QueryContainer>>();
terms.Add(x => x.Term(t => t.Field(f => f.EventName.Suffix("keyword")).Value(eventName)));
terms.Add(x => x.Term(t => t.Field(f => f.EventKey.Suffix("keyword")).Value(eventKey)));
terms.Add(x => x.DateRange(t => t.Field(f => f.EventTime).GreaterThanOrEquals(asOf)));
var response = await client.SearchAsync<Event>(
dsl => dsl.Index(CreateIndex())
.Query(q => q.Bool(b => b.Filter(terms)))
.Source(s => s.Includes(e => e.Field(f => f.Id.Suffix("keyword")))),
ct: cancellationToken);
CheckResponse(response);
return response.Documents.Select(x => x.Id);
}
public virtual async Task<EventSubscription> GetFirstOpenSubscription(string eventName, string eventKey, DateTime asOf, CancellationToken cancellationToken = default)
{
var client = CreateClient();
var terms = new List<Func<QueryContainerDescriptor<EventSubscription>, QueryContainer>>();
terms.Add(x => x.Term(t => t.Field(f => f.EventName.Suffix("keyword")).Value(eventName)));
terms.Add(x => x.Term(t => t.Field(f => f.EventKey.Suffix("keyword")).Value(eventKey)));
terms.Add(x => x.Term(t => t.Field(f => f.ExternalToken.Suffix("keyword")).Value(null)));
terms.Add(x => x.DateRange(t => t.Field(f => f.SubscribeAsOf).LessThanOrEquals(asOf)));
var response = await client.SearchAsync<EventSubscription>(
dsl => dsl.Index(CreateIndex())
.Query(q => q.Bool(b => b.Filter(terms)))
.Source(s => s.Includes(e => e.Field(f => f.Id.Suffix("keyword"))))
.Sort(s => s.Field(f => f.SubscribeAsOf, SortOrder.Ascending))
.Take(1),
ct: cancellationToken);
CheckResponse(response);
return response.Documents.FirstOrDefault();
}
public virtual async Task<IEnumerable<string>> GetRunnableEvents(DateTime asAt, CancellationToken cancellationToken = default)
{
var client = CreateClient();
var now = asAt.ToUniversalTime();
var terms = new List<Func<QueryContainerDescriptor<Event>, QueryContainer>>();
terms.Add(x => x.Term(t => t.Field(f => f.IsProcessed).Value(false)));
terms.Add(x => x.DateRange(t => t.Field(f => f.EventTime).LessThanOrEquals(now)));
var response = await client.SearchAsync<Event>(
dsl => dsl.Index(CreateIndex())
.Query(q => q.Bool(b => b.Filter(terms)))
.Source(s => s.Includes(e => e.Field(f => f.Id.Suffix("keyword")))),
ct: cancellationToken);
CheckResponse(response);
return response.Documents.Select(x => x.Id);
}
public virtual async Task<IEnumerable<string>> GetRunnableInstances(DateTime asAt, CancellationToken cancellationToken = default)
{
var client = CreateClient();
var now = asAt.ToUniversalTime().Ticks;
var terms = new List<Func<QueryContainerDescriptor<WorkflowInstance>, QueryContainer>>();
terms.Add(x => x.LongRange(t => t.Field(f => f.NextExecution).LessThanOrEquals(now)));
terms.Add(x => x.Term(t => t.Field(f => f.Status).Value(WorkflowStatus.Runnable)));
var response = await client.SearchAsync<WorkflowInstance>(
dsl => dsl.Index(CreateIndex())
.Query(q => q.Bool(b => b.Filter(terms)))
.Source(s => s.Includes(e => e.Field(f => f.Id.Suffix("keyword")))),
ct: cancellationToken);
CheckResponse(response);
return response.Documents.Select(x => x.Id);
}
public virtual async Task<EventSubscription> GetSubscription(string eventSubscriptionId, CancellationToken cancellationToken = default)
{
var client = CreateClient();
var id = Guid.Parse(eventSubscriptionId);
var response = await client.GetAsync<EventSubscription>(
id,
dsl => dsl.Index(CreateIndex()),
ct: cancellationToken);
CheckResponse(response);
return response.Source;
}
public virtual async Task<IEnumerable<EventSubscription>> GetSubscriptions(string eventName, string eventKey, DateTime asOf, CancellationToken cancellationToken = default)
{
var client = CreateClient();
var now = asOf.ToUniversalTime();
var terms = new List<Func<QueryContainerDescriptor<EventSubscription>, QueryContainer>>();
terms.Add(x => x.Term(t => t.Field(f => f.EventName.Suffix("keyword")).Value(eventName)));
terms.Add(x => x.Term(t => t.Field(f => f.EventKey.Suffix("keyword")).Value(eventKey)));
terms.Add(x => x.DateRange(t => t.Field(f => f.SubscribeAsOf).LessThanOrEquals(now)));
var response = await client.SearchAsync<EventSubscription>(
dsl => dsl.Index(CreateIndex())
.Query(q => q.Bool(b => b.Filter(terms)))
.Source(s => s.IncludeAll()),
ct: cancellationToken);
CheckResponse(response);
return response.Documents;
}
public virtual async Task<WorkflowInstance> GetWorkflowInstance(string Id, CancellationToken cancellationToken = default)
{
var workflowId = Guid.Parse(Id);
var client = CreateClient();
var response = await client.GetAsync<WorkflowInstance>(
workflowId,
dsl => dsl.Index(CreateIndex()),
ct: cancellationToken);
CheckResponse(response);
return response.Source;
}
public virtual async Task<IEnumerable<WorkflowInstance>> GetWorkflowInstances(WorkflowStatus? status, string type, DateTime? createdFrom, DateTime? createdTo, int skip, int take)
{
var client = CreateClient();
var terms = new List<Func<QueryContainerDescriptor<WorkflowInstance>, QueryContainer>>();
if (status.HasValue)
{
terms.Add(x => x.Term(t => t.Field(f => f.Status).Value(status.Value)));
}
if (!type.IsNullOrWhiteSpace())
{
terms.Add(x => x.Term(t => t.Field(f => f.WorkflowDefinitionId.Suffix("keyword")).Value(type)));
}
if (createdFrom.HasValue)
{
terms.Add(x => x.DateRange(t => t.Field(f => f.CreateTime).GreaterThanOrEquals(createdFrom.Value)));
}
if (createdTo.HasValue)
{
terms.Add(x => x.DateRange(t => t.Field(f => f.CreateTime).LessThanOrEquals(createdTo.Value)));
}
var response = await client.SearchAsync<WorkflowInstance>(
dsl => dsl.Index(CreateIndex())
.Query(q => q.Bool(b => b.Filter(terms)))
.Source(s => s.IncludeAll())
.Skip(skip)
.Take(take));
CheckResponse(response);
return response.Documents;
}
public virtual async Task<IEnumerable<WorkflowInstance>> GetWorkflowInstances(IEnumerable<string> ids, CancellationToken cancellationToken = default)
{
var client = CreateClient();
var response = await client.SearchAsync<WorkflowInstance>(
dsl => dsl.Index(CreateIndex())
.Query(q =>
q.Bool(b =>
b.Should(s =>
s.Terms(t => t.Field(f => f.Id.Suffix("keyword")).Terms(ids)))))
.Source(s => s.IncludeAll()),
ct: cancellationToken);
CheckResponse(response);
return response.Documents;
}
public virtual async Task MarkEventProcessed(string id, CancellationToken cancellationToken = default)
{
var eventId = Guid.Parse(id);
var client = CreateClient();
var response = await client.GetAsync<Event>(
eventId,
dsl => dsl.Index(CreateIndex()),
ct: cancellationToken);
CheckResponse(response);
if (response.Found)
{
response.Source.IsProcessed = true;
await client.UpdateAsync<Event>(
id,
dsl => dsl.Index(CreateIndex())
.Doc(response.Source),
ct: cancellationToken);
}
}
public virtual async Task MarkEventUnprocessed(string id, CancellationToken cancellationToken = default)
{
var eventId = Guid.Parse(id);
var client = CreateClient();
var response = await client.GetAsync<Event>(
eventId,
dsl => dsl.Index(CreateIndex()),
ct: cancellationToken);
CheckResponse(response);
if (response.Found)
{
response.Source.IsProcessed = false;
await client.UpdateAsync<Event>(
id,
dsl => dsl.Index(CreateIndex())
.Doc(response.Source),
ct: cancellationToken);
}
}
public virtual async Task PersistErrors(IEnumerable<ExecutionError> errors, CancellationToken cancellationToken = default)
{
var executionErrors = errors as ExecutionError[] ?? errors.ToArray();
if (executionErrors.Any())
{
var client = CreateClient();
var response = await client.IndexManyAsync(
errors,
CreateIndex(),
cancellationToken: cancellationToken);
CheckResponse(response);
}
}
public virtual async Task PersistWorkflow(WorkflowInstance workflow, CancellationToken cancellationToken = default)
{
var workflowId = Guid.Parse(workflow.Id);
var client = CreateClient();
var response = await client.GetAsync<WorkflowInstance>(
workflowId,
dsl => dsl.Index(CreateIndex()),
ct: cancellationToken);
CheckResponse(response);
await client.UpdateAsync<WorkflowInstance>(
workflowId,
dsl => dsl.Index(CreateIndex())
.Doc(workflow),
ct: cancellationToken);
}
public virtual async Task ProcessCommands(DateTimeOffset asOf, Func<ScheduledCommand, Task> action, CancellationToken cancellationToken = default)
{
var client = CreateClient();
var terms = new List<Func<QueryContainerDescriptor<PersistedScheduledCommand>, QueryContainer>>();
terms.Add(x => x.LongRange(t => t.Field(f => f.ExecuteTime).LessThan(asOf.Ticks)));
var response = await client.SearchAsync<PersistedScheduledCommand>(
dsl => dsl.Index(CreateIndex())
.Query(q => q.Bool(b => b.Filter(terms)))
.Source(s => s.IncludeAll()),
ct: cancellationToken);
CheckResponse(response);
foreach (var command in response.Documents)
{
try
{
await action(command.ToScheduledCommand());
await client.DeleteAsync<PersistedScheduledCommand>(
command.Id,
dsl => dsl.Index(CreateIndex()),
ct: cancellationToken);
}
catch (Exception)
{
//TODO: add logger
}
}
}
public virtual async Task ScheduleCommand(ScheduledCommand command)
{
var persistedCommand = new PersistedScheduledCommand(
_guidGenerator.Create(),
command);
var client = CreateClient();
var response = await client.IndexAsync(
persistedCommand,
dsl => dsl.Index(CreateIndex()).Id(persistedCommand.Id));
CheckResponse(response);
}
public virtual async Task<bool> SetSubscriptionToken(string eventSubscriptionId, string token, string workerId, DateTime expiry, CancellationToken cancellationToken = default)
{
var id = Guid.Parse(eventSubscriptionId);
var client = CreateClient();
var response = await client.GetAsync<EventSubscription>(
id,
dsl => dsl.Index(CreateIndex()),
ct: cancellationToken);
CheckResponse(response);
if (response.Found)
{
response.Source.ExternalToken = token;
response.Source.ExternalWorkerId = workerId;
response.Source.ExternalTokenExpiry = expiry;
var uptResponse = await client.UpdateAsync<EventSubscription>(
id,
dsl => dsl.Index(CreateIndex())
.Doc(response.Source),
ct: cancellationToken);
return uptResponse.Result == Result.Updated;
}
return false;
}
public virtual async Task TerminateSubscription(string eventSubscriptionId, CancellationToken cancellationToken = default)
{
var id = Guid.Parse(eventSubscriptionId);
var client = CreateClient();
var response = await client.DeleteAsync<EventSubscription>(
id,
dsl => dsl.Index(CreateIndex()),
ct: cancellationToken);
CheckResponse(response);
}
private IElasticClient CreateClient()
{
return _elasticsearchClientFactory.Create();
}
private string CreateIndex()
{
return _options.IndexFormat;
}
private void CheckResponse(IResponse response)
{
if (!response.ApiCall.Success)
{
_logger.LogError(default(EventId), response.ApiCall.OriginalException, $"ES Operation Failed");
throw new AbpException($"ES Operation Failed", response.ApiCall.OriginalException);
}
if (!response.IsValid)
{
_logger.LogWarning("ES Request Valid Error: {0}", response.DebugInformation);
throw new InvalidOperationException(response.DebugInformation, response.OriginalException);
}
}
}
}

32
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch/LINGYUN/Abp/WorkflowCore/Persistence/Elasticsearch/Models/PersistedScheduledCommand.cs

@ -0,0 +1,32 @@
using System;
using WorkflowCore.Models;
namespace LINGYUN.Abp.WorkflowCore.Persistence.Elasticsearch.Models
{
public class PersistedScheduledCommand
{
public Guid Id { get; set; }
public string CommandName { get; set; }
public string Data { get; set; }
public long ExecuteTime { get; set; }
public PersistedScheduledCommand() { }
public PersistedScheduledCommand(Guid id, ScheduledCommand command)
{
Id = id;
CommandName = command.CommandName;
Data = command.Data;
ExecuteTime = command.ExecuteTime;
}
public ScheduledCommand ToScheduledCommand()
{
return new ScheduledCommand
{
CommandName = CommandName,
Data = Data,
ExecuteTime = ExecuteTime
};
}
}
}

4
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence/LINGYUN/Abp/WorkflowCore/Persistence/AbpWorkflowCorePersistenceModule.cs

@ -10,8 +10,8 @@ namespace LINGYUN.Abp.WorkflowCore.Persistence
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddSingleton<IPersistenceProvider, AbpWorkflowPersistenceProvider>();
context.Services.AddSingleton<AbpWorkflowPersistenceProvider>();
context.Services.AddTransient<IPersistenceProvider, AbpWorkflowPersistenceProvider>();
context.Services.AddTransient<AbpWorkflowPersistenceProvider>();
PreConfigure<WorkflowOptions>(options =>
{

3
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore.Persistence/LINGYUN/Abp/WorkflowCore/Persistence/AbpWorkflowPersistenceProvider.cs

@ -5,7 +5,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.Linq;
using Volo.Abp.MultiTenancy;
@ -15,7 +14,7 @@ using WorkflowCore.Models;
namespace LINGYUN.Abp.WorkflowCore.Persistence
{
public class AbpWorkflowPersistenceProvider : IPersistenceProvider, IUnitOfWorkEnabled, ITransientDependency
public class AbpWorkflowPersistenceProvider : IPersistenceProvider, IUnitOfWorkEnabled
{
public ILogger<AbpWorkflowPersistenceProvider> Logger { protected get; set; }

6
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore/LINGYUN.Abp.WorkflowCore.csproj

@ -12,7 +12,11 @@
<ItemGroup>
<PackageReference Include="Volo.Abp.Timing" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Threading" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="WorkflowCore.DSL" Version="3.6.1" />
<!--<PackageReference Include="WorkflowCore.DSL" Version="3.6.1" />-->
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\consoles\source\src\WorkflowCore.DSL\WorkflowCore.DSL.csproj" />
</ItemGroup>
</Project>

22
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowCore/LINGYUN/Abp/WorkflowCore/AbpDateTimeProvider.cs

@ -0,0 +1,22 @@
using System;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Timing;
using WorkflowCore.Interface;
namespace LINGYUN.Abp.WorkflowCore
{
[Dependency(ReplaceServices = true)]
public class AbpDateTimeProvider : IDateTimeProvider
{
private readonly IClock _clock;
public AbpDateTimeProvider(IClock clock)
{
_clock = clock;
}
public DateTime Now => _clock.Now;
public DateTime UtcNow => _clock.Now.ToUtcDateTime();
}
}

20
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application.Contracts/LINGYUN.Abp.WorkflowManagement.Application.Contracts.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Authorization" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.WorkflowManagement.Domain.Shared\LINGYUN.Abp.WorkflowManagement.Domain.Shared.csproj" />
</ItemGroup>
</Project>

23
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application.Contracts/LINGYUN/Abp/WorkflowManagement/Authorization/WorkflowManagementPermissionDefinitionProvider.cs

@ -0,0 +1,23 @@
using LINGYUN.Abp.WorkflowManagement.Localization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.WorkflowManagement.Authorization
{
public class WorkflowManagementPermissionDefinitionProvider : PermissionDefinitionProvider
{
public override void Define(IPermissionDefinitionContext context)
{
var group = context.AddGroup(WorkflowManagementPermissions.GroupName, L("Permission:WorkflowManagement"));
group.AddPermission(
WorkflowManagementPermissions.ManageSettings,
L("Permission:ManageSettings"));
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<WorkflowManagementResource>(name);
}
}
}

9
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application.Contracts/LINGYUN/Abp/WorkflowManagement/Authorization/WorkflowManagementPermissions.cs

@ -0,0 +1,9 @@
namespace LINGYUN.Abp.WorkflowManagement.Authorization
{
public static class WorkflowManagementPermissions
{
public const string GroupName = "WorkflowManagement";
public const string ManageSettings = GroupName + ".ManageSettings";
}
}

14
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application.Contracts/LINGYUN/Abp/WorkflowManagement/WorkflowManagementApplicationContractsModule.cs

@ -0,0 +1,14 @@
using Volo.Abp.Application;
using Volo.Abp.Authorization;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.WorkflowManagement
{
[DependsOn(
typeof(AbpAuthorizationModule),
typeof(AbpDddApplicationContractsModule),
typeof(WorkflowManagementDomainSharedModule))]
public class WorkflowManagementApplicationContractsModule : AbpModule
{
}
}

7
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application.Contracts/LINGYUN/Abp/WorkflowManagement/WorkflowManagementRemoteServiceConsts.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.WorkflowManagement
{
public static class WorkflowManagementRemoteServiceConsts
{
public const string RemoteServiceName = "WorkflowManagement";
}
}

20
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application/LINGYUN.Abp.WorkflowManagement.Application.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.WorkflowManagement.Application.Contracts\LINGYUN.Abp.WorkflowManagement.Application.Contracts.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.WorkflowManagement.Domain\LINGYUN.Abp.WorkflowManagement.Domain.csproj" />
</ItemGroup>
</Project>

14
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application/LINGYUN/Abp/WorkflowManagement/WorkflowManagementAppServiceBase.cs

@ -0,0 +1,14 @@
using LINGYUN.Abp.WorkflowManagement.Localization;
using Volo.Abp.Application.Services;
namespace LINGYUN.Abp.WorkflowManagement
{
public abstract class WorkflowManagementAppServiceBase : ApplicationService
{
protected WorkflowManagementAppServiceBase()
{
LocalizationResource = typeof(WorkflowManagementResource);
ObjectMapperContext = typeof(WorkflowManagementApplicationModule);
}
}
}

11
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application/LINGYUN/Abp/WorkflowManagement/WorkflowManagementApplicationMapperProfile.cs

@ -0,0 +1,11 @@
using AutoMapper;
namespace LINGYUN.Abp.WorkflowManagement
{
public class WorkflowManagementApplicationMapperProfile : Profile
{
public WorkflowManagementApplicationMapperProfile()
{
}
}
}

25
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Application/LINGYUN/Abp/WorkflowManagement/WorkflowManagementApplicationModule.cs

@ -0,0 +1,25 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Application;
using Volo.Abp.Authorization;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.WorkflowManagement
{
[DependsOn(
typeof(AbpAuthorizationModule),
typeof(AbpDddApplicationContractsModule),
typeof(WorkflowManagementDomainSharedModule))]
public class WorkflowManagementApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<WorkflowManagementApplicationModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<WorkflowManagementApplicationMapperProfile>(validate: true);
});
}
}
}

27
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain.Shared/LINGYUN.Abp.WorkflowManagement.Domain.Shared.csproj

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\WorkflowManagement\Localization\Resources\en.json" />
<None Remove="LINGYUN\Abp\WorkflowManagement\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\WorkflowManagement\Localization\Resources\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\WorkflowManagement\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Auditing" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.EventBus" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Localization" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
</Project>

7
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain.Shared/LINGYUN/Abp/WorkflowManagement/Localization/Resources/en.json

@ -0,0 +1,7 @@
{
"culture": "en",
"texts": {
"Permission:WorkflowManagement": "WorkflowManagement",
"Permission:ManageSettings": "Manage Settings"
}
}

7
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain.Shared/LINGYUN/Abp/WorkflowManagement/Localization/Resources/zh-Hans.json

@ -0,0 +1,7 @@
{
"culture": "zh-Hans",
"texts": {
"Permission:WorkflowManagement": "WorkflowManagement",
"Permission:ManageSettings": "管理设置"
}
}

9
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain.Shared/LINGYUN/Abp/WorkflowManagement/Localization/WorkflowManagementResource.cs

@ -0,0 +1,9 @@
using Volo.Abp.Localization;
namespace LINGYUN.Abp.WorkflowManagement.Localization
{
[LocalizationResourceName("WorkflowManagement")]
public class WorkflowManagementResource
{
}
}

33
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain.Shared/LINGYUN/Abp/WorkflowManagement/WorkflowManagementDomainSharedModule.cs

@ -0,0 +1,33 @@
using LINGYUN.Abp.WorkflowManagement.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.WorkflowManagement
{
[DependsOn(
typeof(AbpLocalizationModule))]
public class WorkflowManagementDomainSharedModule: AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<WorkflowManagementDomainSharedModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<WorkflowManagementResource>()
.AddVirtualJson("/Abp/WorkflowManagement/Localization/Resources");
});
Configure<AbpExceptionLocalizationOptions>(options =>
{
options.MapCodeNamespace(WorkflowManagementErrorCodes.Namespace, typeof(WorkflowManagementResource));
});
}
}
}

7
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain.Shared/LINGYUN/Abp/WorkflowManagement/WorkflowManagementErrorCodes.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.WorkflowManagement
{
public static class WorkflowManagementErrorCodes
{
public const string Namespace = "WorkflowManagement";
}
}

22
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN.Abp.WorkflowManagement.Domain.csproj

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AutoMapper" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Caching" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.WorkflowCore\LINGYUN.Abp.WorkflowCore.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.WorkflowManagement.Domain.Shared\LINGYUN.Abp.WorkflowManagement.Domain.Shared.csproj" />
</ItemGroup>
</Project>

11
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/Settings/WorkflowManagementSettingDefinitionProvider.cs

@ -0,0 +1,11 @@
using Volo.Abp.Settings;
namespace LINGYUN.Abp.WorkflowManagement.Settings
{
public class WorkflowManagementSettingDefinitionProvider : SettingDefinitionProvider
{
public override void Define(ISettingDefinitionContext context)
{
}
}
}

7
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/Settings/WorkflowManagementSettings.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.WorkflowManagement.Settings
{
public static class WorkflowManagementSettings
{
public const string GroupName = "WorkflowManagement";
}
}

57
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/Step.cs

@ -0,0 +1,57 @@
using System;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
using WorkflowCore.Models;
namespace LINGYUN.Abp.WorkflowManagement
{
public class Step : Entity<Guid>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid WorkflowId { get; protected set; }
public virtual string Name { get; protected set;}
public virtual string StepType { get; protected set; }
public virtual string CancelCondition { get; set; }
public virtual WorkflowErrorHandling? ErrorBehavior { get; protected set; }
public virtual int? RetryInterval { get; set; }
public virtual bool Saga { get; set; }
public virtual Guid? NextStep { get; protected set; }
public virtual ExtraPropertyDictionary Inputs { get; set; }
public virtual ExtraPropertyDictionary Outputs { get; set; }
public virtual ExtraPropertyDictionary SelectNextStep { get; set; }
protected Step()
{
Inputs = new ExtraPropertyDictionary();
Outputs = new ExtraPropertyDictionary();
SelectNextStep = new ExtraPropertyDictionary();
}
public Step(
Guid id,
Guid workflowId,
string name,
string stepType,
string cancelCondition,
WorkflowErrorHandling? errorBehavior = null,
int? retryInterval = null,
bool saga = false,
Guid? nextStep = null,
Guid? tenantId = null) : base(id)
{
Name = name;
WorkflowId = workflowId;
StepType = stepType;
CancelCondition = cancelCondition;
ErrorBehavior = errorBehavior;
RetryInterval = retryInterval;
Saga = saga;
NextStep = nextStep;
TenantId = tenantId;
Inputs = new ExtraPropertyDictionary();
Outputs = new ExtraPropertyDictionary();
SelectNextStep = new ExtraPropertyDictionary();
}
}
}

45
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/Workflow.cs

@ -0,0 +1,45 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.WorkflowManagement
{
/// <summary>
/// 流程定义
/// </summary>
public class Workflow : AuditedAggregateRoot<Guid>, IMultiTenant
{
/// <summary>
/// 租户标识
/// </summary>
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 是否启用
/// </summary>
public virtual bool IsEnabled { get; protected set; }
/// <summary>
/// 显示名称
/// </summary>
public virtual string DisplayName { get; set; }
/// <summary>
/// 描述
/// </summary>
public virtual string Description { get; set; }
/// <summary>
/// 版本号
/// </summary>
public virtual int Version { get; protected set; }
protected Workflow()
{
}
public Workflow(
Guid id,
string displayName,
string description = "",
int version = 1) : base(id)
{
}
}
}

12
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/WorkflowManagementDbProperties.cs

@ -0,0 +1,12 @@
namespace LINGYUN.Abp.WorkflowManagement
{
public static class WorkflowManagementDbProperties
{
public static string DbTablePrefix { get; set; } = "WorkflowManagement_";
public static string DbSchema { get; set; } = null;
public const string ConnectionStringName = "WorkflowManagement";
}
}

12
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/WorkflowManagementDomainMapperProfile.cs

@ -0,0 +1,12 @@
using AutoMapper;
namespace LINGYUN.Abp.WorkflowManagement
{
public class WorkflowManagementDomainMapperProfile: Profile
{
public WorkflowManagementDomainMapperProfile()
{
}
}
}

27
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.Domain/LINGYUN/Abp/WorkflowManagement/WorkflowManagementDomainModule.cs

@ -0,0 +1,27 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.WorkflowManagement
{
[DependsOn(
typeof(AbpAutoMapperModule),
typeof(WorkflowManagementDomainSharedModule))]
public class WorkflowManagementDomainModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<WorkflowManagementDomainModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<WorkflowManagementDomainMapperProfile>(validate: true);
});
Configure<AbpDistributedEntityEventOptions>(options =>
{
});
}
}
}

19
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore.csproj

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.WorkflowManagement.Domain\LINGYUN.Abp.WorkflowManagement.Domain.csproj" />
</ItemGroup>
</Project>

10
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore/LINGYUN/Abp/WorkflowManagement/EntityFrameworkCore/IWorkflowManagementDbContext.cs

@ -0,0 +1,10 @@
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore
{
[ConnectionStringName(WorkflowManagementDbProperties.ConnectionStringName)]
public interface IWorkflowManagementDbContext : IEfCoreDbContext
{
}
}

20
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore/LINGYUN/Abp/WorkflowManagement/EntityFrameworkCore/WorkflowManagementDbContext.cs

@ -0,0 +1,20 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore
{
public class WorkflowManagementDbContext : AbpDbContext<WorkflowManagementDbContext>, IWorkflowManagementDbContext
{
public WorkflowManagementDbContext(
DbContextOptions<WorkflowManagementDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ConfigureWorkflowManagement();
}
}
}

22
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore/LINGYUN/Abp/WorkflowManagement/EntityFrameworkCore/WorkflowManagementDbContextModelCreatingExtensions.cs

@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore;
using System;
using Volo.Abp;
namespace LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore
{
public static class WorkflowManagementDbContextModelCreatingExtensions
{
public static void ConfigureWorkflowManagement(
this ModelBuilder builder,
Action<WorkflowManagementModelBuilderConfigurationOptions> optionsAction = null)
{
Check.NotNull(builder, nameof(builder));
var options = new WorkflowManagementModelBuilderConfigurationOptions(
WorkflowManagementDbProperties.DbTablePrefix,
WorkflowManagementDbProperties.DbSchema
);
optionsAction?.Invoke(options);
}
}
}

20
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore/LINGYUN/Abp/WorkflowManagement/EntityFrameworkCore/WorkflowManagementEntityFrameworkCoreModule.cs

@ -0,0 +1,20 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore
{
[DependsOn(
typeof(WorkflowManagementDomainModule),
typeof(AbpEntityFrameworkCoreModule))]
public class WorkflowManagementEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<WorkflowManagementDbContext>(options =>
{
options.AddDefaultRepositories(includeAllEntities: true);
});
}
}
}

18
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore/LINGYUN/Abp/WorkflowManagement/EntityFrameworkCore/WorkflowManagementModelBuilderConfigurationOptions.cs

@ -0,0 +1,18 @@
using JetBrains.Annotations;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace LINGYUN.Abp.WorkflowManagement.EntityFrameworkCore
{
public class WorkflowManagementModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions
{
public WorkflowManagementModelBuilderConfigurationOptions(
[NotNull] string tablePrefix = "",
[CanBeNull] string schema = null)
: base(
tablePrefix,
schema)
{
}
}
}

19
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.HttpApi/LINGYUN.Abp.WorkflowManagement.HttpApi.csproj

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.WorkflowManagement.Application.Contracts\LINGYUN.Abp.WorkflowManagement.Application.Contracts.csproj" />
</ItemGroup>
</Project>

41
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.HttpApi/LINGYUN/Abp/WorkflowManagement/WorkflowManagementHttpApiModule.cs

@ -0,0 +1,41 @@
using LINGYUN.Abp.WorkflowManagement.Localization;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Validation.Localization;
namespace LINGYUN.Abp.WorkflowManagement
{
[DependsOn(
typeof(AbpAspNetCoreMvcModule),
typeof(WorkflowManagementApplicationContractsModule))]
public class WorkflowManagementHttpApiModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
mvcBuilder.AddApplicationPartIfNotExists(typeof(WorkflowManagementHttpApiModule).Assembly);
});
PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
{
options.AddAssemblyResource(
typeof(WorkflowManagementResource),
typeof(WorkflowManagementApplicationContractsModule).Assembly);
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<WorkflowManagementResource>()
.AddBaseTypes(typeof(AbpValidationResource));
});
}
}
}

20
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.SettingManagement/LINGYUN.Abp.WorkflowManagement.SettingManagement.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../common.props" />
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.SettingManagement.Domain" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="LINGYUN.Abp.SettingManagement.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.WorkflowManagement.Application.Contracts\LINGYUN.Abp.WorkflowManagement.Application.Contracts.csproj" />
</ItemGroup>
</Project>

77
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.SettingManagement/LINGYUN/Abp/WorkflowManagement/SettingManagement/SettingAppService.cs

@ -0,0 +1,77 @@
using LINGYUN.Abp.WorkflowManagement.Authorization;
using LINGYUN.Abp.WorkflowManagement.Localization;
using LINGYUN.Abp.SettingManagement;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Features;
using Volo.Abp.MultiTenancy;
using Volo.Abp.SettingManagement;
using Volo.Abp.Settings;
namespace LINGYUN.Abp.WorkflowManagement.SettingManagement
{
[Authorize(WorkflowManagementPermissions.ManageSettings)]
public class SettingAppService : ApplicationService, ISettingAppService
{
protected ISettingManager SettingManager { get; }
protected ISettingDefinitionManager SettingDefinitionManager { get; }
public SettingAppService(
ISettingManager settingManager,
ISettingDefinitionManager settingDefinitionManager)
{
SettingManager = settingManager;
SettingDefinitionManager = settingDefinitionManager;
LocalizationResource = typeof(WorkflowManagementResource);
}
public virtual async Task<ListResultDto<SettingGroupDto>> GetAllForCurrentTenantAsync()
{
return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString());
}
public virtual async Task SetCurrentTenantAsync(UpdateSettingsDto input)
{
// 增加特性检查
await CheckFeatureAsync();
if (CurrentTenant.IsAvailable)
{
foreach (var setting in input.Settings)
{
await SettingManager.SetForTenantAsync(CurrentTenant.GetId(), setting.Name, setting.Value);
}
await CurrentUnitOfWork.SaveChangesAsync();
}
}
protected virtual async Task CheckFeatureAsync()
{
await FeatureChecker.CheckEnabledAsync(SettingManagementFeatures.Enable);
}
protected virtual async Task<ListResultDto<SettingGroupDto>> GetAllForProviderAsync(string providerName, string providerKey)
{
var settingGroups = new List<SettingGroupDto>();
await Task.CompletedTask;
return new ListResultDto<SettingGroupDto>(settingGroups);
}
public Task SetGlobalAsync(UpdateSettingsDto input)
{
throw new NotSupportedException();
}
public Task<ListResultDto<SettingGroupDto>> GetAllForGlobalAsync()
{
throw new NotSupportedException();
}
}
}

48
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.SettingManagement/LINGYUN/Abp/WorkflowManagement/SettingManagement/SettingController.cs

@ -0,0 +1,48 @@
using LINGYUN.Abp.SettingManagement;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc;
namespace LINGYUN.Abp.WorkflowManagement.SettingManagement
{
[RemoteService(Name = WorkflowManagementRemoteServiceConsts.RemoteServiceName)]
[ApiVersion("2.0")]
[Area("WorkflowManagement")]
[Route("api/WorkflowManagement/settings")]
public class SettingController : AbpController, ISettingAppService
{
private readonly ISettingAppService _settingAppService;
public SettingController(ISettingAppService settingAppService)
{
_settingAppService = settingAppService;
}
[HttpPut]
public virtual async Task SetCurrentTenantAsync(UpdateSettingsDto input)
{
await _settingAppService.SetCurrentTenantAsync(input);
}
[HttpGet]
public virtual async Task<ListResultDto<SettingGroupDto>> GetAllForCurrentTenantAsync()
{
return await _settingAppService.GetAllForCurrentTenantAsync();
}
[HttpPost]
[Route("by-global")]
public virtual async Task SetGlobalAsync(UpdateSettingsDto input)
{
await _settingAppService.SetGlobalAsync(input);
}
[HttpGet]
[Route("by-global")]
public virtual async Task<ListResultDto<SettingGroupDto>> GetAllForGlobalAsync()
{
return await _settingAppService.GetAllForGlobalAsync();
}
}
}

15
aspnet-core/modules/workflow/LINGYUN.Abp.WorkflowManagement.SettingManagement/LINGYUN/Abp/WorkflowManagement/SettingManagement/WorkflowManagementSettingManagementModule.cs

@ -0,0 +1,15 @@
using LINGYUN.Abp.SettingManagement;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Modularity;
using Volo.Abp.SettingManagement;
namespace LINGYUN.Abp.WorkflowManagement.SettingManagement
{
[DependsOn(
typeof(AbpSettingManagementApplicationContractsModule),
typeof(AbpAspNetCoreMvcModule),
typeof(AbpSettingManagementDomainModule))]
public class WorkflowManagementSettingManagementModule : AbpModule
{
}
}
Loading…
Cancel
Save