43 changed files with 1737 additions and 389 deletions
@ -0,0 +1,33 @@ |
|||||
|
using Microsoft.Extensions.Logging; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Volo.Abp.ExceptionHandling; |
||||
|
using WorkflowCore.Interface; |
||||
|
using WorkflowCore.Models; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WorkflowCore.ExceptionHandling |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 不会自动注册到容器
|
||||
|
/// 需要时手动注册
|
||||
|
/// </summary>
|
||||
|
public class ExceptionNotifierHandler : IWorkflowErrorHandler |
||||
|
{ |
||||
|
public WorkflowErrorHandling Type => WorkflowErrorHandling.Terminate; |
||||
|
|
||||
|
private readonly IExceptionNotifier _exceptionNotifier; |
||||
|
|
||||
|
public ExceptionNotifierHandler(IExceptionNotifier exceptionNotifier) |
||||
|
{ |
||||
|
_exceptionNotifier = exceptionNotifier; |
||||
|
} |
||||
|
|
||||
|
public void Handle(WorkflowInstance workflow, WorkflowDefinition def, ExecutionPointer pointer, WorkflowStep step, Exception exception, Queue<ExecutionPointer> bubbleUpQueue) |
||||
|
{ |
||||
|
_ = _exceptionNotifier.NotifyAsync( |
||||
|
new ExceptionNotificationContext( |
||||
|
exception, |
||||
|
LogLevel.Warning)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
namespace LINGYUN.Abp.WorkflowCore |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 实现接口用于启动多租户
|
||||
|
/// </summary>
|
||||
|
public interface IStepMultiTenant |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
using Microsoft.Extensions.Logging; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Features; |
||||
|
using WorkflowCore.Interface; |
||||
|
using WorkflowCore.Models; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WorkflowCore.Middleware |
||||
|
{ |
||||
|
public class FeatureCheckWorkflowMiddleware : IWorkflowMiddleware |
||||
|
{ |
||||
|
private readonly IFeatureChecker _featureChecker; |
||||
|
private readonly ILogger<FeatureCheckWorkflowMiddleware> _logger; |
||||
|
public WorkflowMiddlewarePhase Phase => WorkflowMiddlewarePhase.PreWorkflow; |
||||
|
|
||||
|
public FeatureCheckWorkflowMiddleware( |
||||
|
IFeatureChecker featureChecker, |
||||
|
ILogger<FeatureCheckWorkflowMiddleware> logger) |
||||
|
{ |
||||
|
_featureChecker = featureChecker; |
||||
|
_logger = logger; |
||||
|
} |
||||
|
|
||||
|
public async Task HandleAsync(WorkflowInstance workflow, WorkflowDelegate next) |
||||
|
{ |
||||
|
if (workflow.Data is IDictionary<string, object> dictionary && |
||||
|
dictionary.TryGetValue(WorkflowCoreConsts.FeatureField, out var defFeatures)) |
||||
|
{ |
||||
|
var requiresFeatures = defFeatures.ToString().Split(';'); |
||||
|
var passed = await _featureChecker.IsEnabledAsync(requiresAll: true, requiresFeatures); |
||||
|
if (!passed) |
||||
|
{ |
||||
|
_logger.LogWarning("Workflow {0} was forcibly terminated for the following reasons: These required functions must be enabled: {1}", |
||||
|
workflow.Id, |
||||
|
requiresFeatures); |
||||
|
workflow.Status = WorkflowStatus.Terminated; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
await next(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
using Microsoft.Extensions.Options; |
||||
|
using Newtonsoft.Json.Linq; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using WorkflowCore.Interface; |
||||
|
using WorkflowCore.Models; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WorkflowCore.Middleware |
||||
|
{ |
||||
|
public class MultiTenancyStepMiddleware : IWorkflowStepMiddleware |
||||
|
{ |
||||
|
private readonly AbpMultiTenancyOptions _multiTenancyOptions; |
||||
|
private readonly ICurrentTenant _currentTenant; |
||||
|
|
||||
|
public MultiTenancyStepMiddleware( |
||||
|
ICurrentTenant currentTenant, |
||||
|
IOptions<AbpMultiTenancyOptions> options) |
||||
|
{ |
||||
|
_currentTenant = currentTenant; |
||||
|
_multiTenancyOptions = options.Value; |
||||
|
} |
||||
|
|
||||
|
public async Task<ExecutionResult> HandleAsync(IStepExecutionContext context, IStepBody body, WorkflowStepDelegate next) |
||||
|
{ |
||||
|
// 触发多租户中间件条件
|
||||
|
// 1、需要启用多租户
|
||||
|
// 2、步骤需要实现接口 IStepMultiTenant
|
||||
|
// 3.1、传递的工作流实现接口 IMultiTenant
|
||||
|
// 3.2、传递的工作流数据包含 TenantId 字段
|
||||
|
|
||||
|
if (!_multiTenancyOptions.IsEnabled) |
||||
|
{ |
||||
|
return await next(); |
||||
|
} |
||||
|
|
||||
|
if (typeof(IStepMultiTenant).IsAssignableFrom(body.GetType())) |
||||
|
{ |
||||
|
if (context.Workflow.Data != null) |
||||
|
{ |
||||
|
if (context.Workflow.Data is IMultiTenant tenant) |
||||
|
{ |
||||
|
using (_currentTenant.Change(tenant.TenantId)) |
||||
|
{ |
||||
|
return await next(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var dataObj = JObject.FromObject(context.Workflow.Data); |
||||
|
var tenantToken = dataObj.GetOrDefault(nameof(IMultiTenant.TenantId)); |
||||
|
if (tenantToken?.HasValues == true) |
||||
|
{ |
||||
|
using (_currentTenant.Change(tenantToken.Value<Guid?>())) |
||||
|
{ |
||||
|
return await next(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return await next(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace LINGYUN.Abp.WorkflowCore |
||||
|
{ |
||||
|
public static class WorkflowCoreConsts |
||||
|
{ |
||||
|
public const string FeatureField = "Feature"; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
namespace LINGYUN.Abp.WorkflowManagement.Workflows |
||||
|
{ |
||||
|
public class WorkflowDataDto |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 名称
|
||||
|
/// </summary>
|
||||
|
public string Name { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 显示名称
|
||||
|
/// </summary>
|
||||
|
public string DisplayName { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 数据类型
|
||||
|
/// </summary>
|
||||
|
public DataType DataType { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 是否必输
|
||||
|
/// 默认: false
|
||||
|
/// </summary>
|
||||
|
public bool IsRequired { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 是否区分大小写
|
||||
|
/// 默认: false
|
||||
|
/// 暂无用
|
||||
|
/// </summary>
|
||||
|
public bool IsCaseSensitive { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
namespace LINGYUN.Abp.WorkflowManagement |
||||
|
{ |
||||
|
public enum DataType |
||||
|
{ |
||||
|
Object, |
||||
|
String, |
||||
|
Number, |
||||
|
Date, |
||||
|
DateTime, |
||||
|
Booleaen |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
namespace LINGYUN.Abp.WorkflowManagement |
||||
|
{ |
||||
|
public static class WorkflowDataConsts |
||||
|
{ |
||||
|
public static int MaxNameLength { get; set; } = 100; |
||||
|
public static int MaxDisplayNameLength { get; set; } = 100; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,108 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.Domain.Entities; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WorkflowManagement |
||||
|
{ |
||||
|
public class WorkflowData : Entity<Guid>, IMultiTenant |
||||
|
{ |
||||
|
public virtual Guid? TenantId { get; protected set; } |
||||
|
public virtual Guid WorkflowId { get; protected set; } |
||||
|
/// <summary>
|
||||
|
/// 名称
|
||||
|
/// </summary>
|
||||
|
public virtual string Name { get; protected set; } |
||||
|
/// <summary>
|
||||
|
/// 显示名称
|
||||
|
/// </summary>
|
||||
|
public virtual string DisplayName { get; protected set; } |
||||
|
/// <summary>
|
||||
|
/// 数据类型
|
||||
|
/// </summary>
|
||||
|
public virtual DataType DataType { get; protected set; } |
||||
|
/// <summary>
|
||||
|
/// 是否必输
|
||||
|
/// 默认: false
|
||||
|
/// </summary>
|
||||
|
public virtual bool IsRequired { get; protected set; } |
||||
|
/// <summary>
|
||||
|
/// 是否区分大小写
|
||||
|
/// 默认: false
|
||||
|
/// 暂无用
|
||||
|
/// </summary>
|
||||
|
public virtual bool IsCaseSensitive { get; protected set; } |
||||
|
protected WorkflowData() { } |
||||
|
public WorkflowData( |
||||
|
Guid id, |
||||
|
Guid workflowId, |
||||
|
string name, |
||||
|
string displayName, |
||||
|
DataType dataType = DataType.String, |
||||
|
bool isRequired = false, |
||||
|
bool isCaseSensitive = false, |
||||
|
Guid? tenantId = null) : base(id) |
||||
|
{ |
||||
|
WorkflowId = workflowId; |
||||
|
Name = name; |
||||
|
DisplayName = displayName; |
||||
|
DataType = dataType; |
||||
|
IsRequired = isRequired; |
||||
|
IsCaseSensitive = isCaseSensitive; |
||||
|
TenantId = tenantId; |
||||
|
} |
||||
|
|
||||
|
public bool TryParse(object input, out object value) |
||||
|
{ |
||||
|
if (input == null) |
||||
|
{ |
||||
|
if (IsRequired) |
||||
|
{ |
||||
|
throw new BusinessException(WorkflowManagementErrorCodes.InvalidInputNullable) |
||||
|
.WithData("Property", DisplayName); |
||||
|
} |
||||
|
// 字典类型不能为空
|
||||
|
value = new { }; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
switch (DataType) |
||||
|
{ |
||||
|
case DataType.String: |
||||
|
value = input.ToString(); |
||||
|
return true; |
||||
|
case DataType.Booleaen: |
||||
|
if (input is bool boValue) |
||||
|
{ |
||||
|
value = boValue; |
||||
|
return true; |
||||
|
} |
||||
|
value = input.ToString().ToLower() == "true"; |
||||
|
return true; |
||||
|
case DataType.Date: |
||||
|
case DataType.DateTime: |
||||
|
if (input is DateTime dateValue) |
||||
|
{ |
||||
|
value = DataType == DataType.Date |
||||
|
? dateValue.Date |
||||
|
: dateValue; |
||||
|
return true; |
||||
|
} |
||||
|
value = DateTime.Parse(input.ToString()); |
||||
|
return true; |
||||
|
case DataType.Number: |
||||
|
if (int.TryParse(input.ToString(), out int intValue)) |
||||
|
{ |
||||
|
value = intValue; |
||||
|
return true; |
||||
|
} |
||||
|
value = 0; |
||||
|
return false; |
||||
|
case DataType.Object: |
||||
|
default: |
||||
|
value = input; |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,13 +1,12 @@ |
|||||
using Microsoft.AspNetCore.Mvc; |
using Microsoft.AspNetCore.Mvc; |
||||
using Volo.Abp.AspNetCore.Mvc; |
using Volo.Abp.AspNetCore.Mvc; |
||||
|
|
||||
namespace LY.MicroService.WorkflowManagement.Controllers |
namespace LY.MicroService.WorkflowManagement.Controllers; |
||||
|
|
||||
|
public class HomeController : AbpController |
||||
{ |
{ |
||||
public class HomeController : AbpController |
public IActionResult Index() |
||||
{ |
{ |
||||
public IActionResult Index() |
return Redirect("/swagger/index.html"); |
||||
{ |
|
||||
return Redirect("/swagger/index.html"); |
|
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,610 @@ |
|||||
|
// <auto-generated />
|
||||
|
using System; |
||||
|
using LY.MicroService.WorkflowManagement.EntityFrameworkCore; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using Microsoft.EntityFrameworkCore.Infrastructure; |
||||
|
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
||||
|
using Volo.Abp.EntityFrameworkCore; |
||||
|
|
||||
|
#nullable disable |
||||
|
|
||||
|
namespace LY.MicroService.WorkflowManagement.Migrations |
||||
|
{ |
||||
|
[DbContext(typeof(WorkflowManagementMigrationsDbContext))] |
||||
|
[Migration("20211214085456_Add-Entity-Workflow-Data-With-WF-Management")] |
||||
|
partial class AddEntityWorkflowDataWithWFManagement |
||||
|
{ |
||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
||||
|
{ |
||||
|
#pragma warning disable 612, 618
|
||||
|
modelBuilder |
||||
|
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) |
||||
|
.HasAnnotation("ProductVersion", "6.0.0") |
||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 64); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowCore.Persistence.PersistedEvent", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.Property<DateTime>("CreationTime") |
||||
|
.HasColumnType("datetime(6)") |
||||
|
.HasColumnName("CreationTime"); |
||||
|
|
||||
|
b.Property<string>("EventData") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<string>("EventKey") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<string>("EventName") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<bool>("IsProcessed") |
||||
|
.HasColumnType("tinyint(1)"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("TenantId"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("CreationTime"); |
||||
|
|
||||
|
b.HasIndex("IsProcessed"); |
||||
|
|
||||
|
b.HasIndex("EventName", "EventKey"); |
||||
|
|
||||
|
b.ToTable("WF_Event", (string)null); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowCore.Persistence.PersistedExecutionError", b => |
||||
|
{ |
||||
|
b.Property<int>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.Property<DateTime>("ErrorTime") |
||||
|
.HasColumnType("datetime(6)"); |
||||
|
|
||||
|
b.Property<Guid>("ExecutionPointerId") |
||||
|
.HasMaxLength(50) |
||||
|
.HasColumnType("char(50)"); |
||||
|
|
||||
|
b.Property<string>("Message") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("TenantId"); |
||||
|
|
||||
|
b.Property<Guid>("WorkflowId") |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.ToTable("WF_ExecutionError", (string)null); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowCore.Persistence.PersistedExecutionPointer", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasMaxLength(50) |
||||
|
.HasColumnType("char(50)"); |
||||
|
|
||||
|
b.Property<bool>("Active") |
||||
|
.HasColumnType("tinyint(1)"); |
||||
|
|
||||
|
b.Property<string>("Children") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<string>("ContextItem") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<DateTime?>("EndTime") |
||||
|
.HasColumnType("datetime(6)"); |
||||
|
|
||||
|
b.Property<string>("EventData") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<string>("EventKey") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<string>("EventName") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<bool>("EventPublished") |
||||
|
.HasColumnType("tinyint(1)"); |
||||
|
|
||||
|
b.Property<string>("Outcome") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<string>("PersistenceData") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<string>("PredecessorId") |
||||
|
.HasMaxLength(100) |
||||
|
.HasColumnType("varchar(100)"); |
||||
|
|
||||
|
b.Property<int>("RetryCount") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.Property<string>("Scope") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<DateTime?>("SleepUntil") |
||||
|
.HasColumnType("datetime(6)"); |
||||
|
|
||||
|
b.Property<DateTime?>("StartTime") |
||||
|
.HasColumnType("datetime(6)"); |
||||
|
|
||||
|
b.Property<int>("Status") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.Property<int>("StepId") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.Property<string>("StepName") |
||||
|
.HasMaxLength(100) |
||||
|
.HasColumnType("varchar(100)"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("TenantId"); |
||||
|
|
||||
|
b.Property<Guid>("WorkflowId") |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("WorkflowId"); |
||||
|
|
||||
|
b.ToTable("WF_ExecutionPointer", (string)null); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowCore.Persistence.PersistedExtensionAttribute", b => |
||||
|
{ |
||||
|
b.Property<long>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("bigint"); |
||||
|
|
||||
|
b.Property<Guid>("ExecutionPointerId") |
||||
|
.HasMaxLength(50) |
||||
|
.HasColumnType("char(50)"); |
||||
|
|
||||
|
b.Property<string>("Key") |
||||
|
.HasMaxLength(100) |
||||
|
.HasColumnType("varchar(100)"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("TenantId"); |
||||
|
|
||||
|
b.Property<string>("Value") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("ExecutionPointerId"); |
||||
|
|
||||
|
b.ToTable("WF_ExtensionAttribute", (string)null); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowCore.Persistence.PersistedScheduledCommand", b => |
||||
|
{ |
||||
|
b.Property<long>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("bigint"); |
||||
|
|
||||
|
b.Property<string>("CommandName") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<string>("Data") |
||||
|
.HasMaxLength(500) |
||||
|
.HasColumnType("varchar(500)"); |
||||
|
|
||||
|
b.Property<long>("ExecuteTime") |
||||
|
.HasColumnType("bigint"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("TenantId"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("ExecuteTime"); |
||||
|
|
||||
|
b.HasIndex("CommandName", "Data") |
||||
|
.IsUnique(); |
||||
|
|
||||
|
b.ToTable("WF_ScheduledCommand", (string)null); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowCore.Persistence.PersistedSubscription", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.Property<string>("EventKey") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<string>("EventName") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<Guid>("ExecutionPointerId") |
||||
|
.HasMaxLength(50) |
||||
|
.HasColumnType("char(50)"); |
||||
|
|
||||
|
b.Property<string>("ExternalToken") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<DateTime?>("ExternalTokenExpiry") |
||||
|
.HasColumnType("datetime(6)"); |
||||
|
|
||||
|
b.Property<string>("ExternalWorkerId") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<int>("StepId") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.Property<DateTime>("SubscribeAsOf") |
||||
|
.HasColumnType("datetime(6)"); |
||||
|
|
||||
|
b.Property<string>("SubscriptionData") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("TenantId"); |
||||
|
|
||||
|
b.Property<Guid>("WorkflowId") |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("EventKey"); |
||||
|
|
||||
|
b.HasIndex("EventName"); |
||||
|
|
||||
|
b.ToTable("WF_Subscription", (string)null); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowCore.Persistence.PersistedWorkflow", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.Property<DateTime?>("CompleteTime") |
||||
|
.HasColumnType("datetime(6)"); |
||||
|
|
||||
|
b.Property<string>("ConcurrencyStamp") |
||||
|
.IsConcurrencyToken() |
||||
|
.HasMaxLength(40) |
||||
|
.HasColumnType("varchar(40)") |
||||
|
.HasColumnName("ConcurrencyStamp"); |
||||
|
|
||||
|
b.Property<DateTime>("CreationTime") |
||||
|
.HasColumnType("datetime(6)") |
||||
|
.HasColumnName("CreationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("CreatorId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("CreatorId"); |
||||
|
|
||||
|
b.Property<string>("Data") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<string>("Description") |
||||
|
.HasMaxLength(500) |
||||
|
.HasColumnType("varchar(500)"); |
||||
|
|
||||
|
b.Property<string>("ExtraProperties") |
||||
|
.HasColumnType("longtext") |
||||
|
.HasColumnName("ExtraProperties"); |
||||
|
|
||||
|
b.Property<DateTime?>("LastModificationTime") |
||||
|
.HasColumnType("datetime(6)") |
||||
|
.HasColumnName("LastModificationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("LastModifierId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("LastModifierId"); |
||||
|
|
||||
|
b.Property<long?>("NextExecution") |
||||
|
.HasColumnType("bigint"); |
||||
|
|
||||
|
b.Property<string>("Reference") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<int>("Status") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("TenantId"); |
||||
|
|
||||
|
b.Property<int>("Version") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.Property<string>("WorkflowDefinitionId") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("NextExecution"); |
||||
|
|
||||
|
b.ToTable("WF_Workflow", (string)null); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowManagement.CompensateNode", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.Property<string>("CancelCondition") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<int?>("ErrorBehavior") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.Property<string>("Inputs") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.HasMaxLength(100) |
||||
|
.HasColumnType("varchar(100)"); |
||||
|
|
||||
|
b.Property<string>("Outputs") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<Guid?>("ParentId") |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.Property<TimeSpan?>("RetryInterval") |
||||
|
.HasColumnType("time(6)"); |
||||
|
|
||||
|
b.Property<bool>("Saga") |
||||
|
.HasColumnType("tinyint(1)"); |
||||
|
|
||||
|
b.Property<string>("SelectNextStep") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<string>("StepType") |
||||
|
.HasMaxLength(100) |
||||
|
.HasColumnType("varchar(100)"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("TenantId"); |
||||
|
|
||||
|
b.Property<Guid>("WorkflowId") |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.ToTable("WF_Compensate", (string)null); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowManagement.StepNode", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.Property<string>("CancelCondition") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<int?>("ErrorBehavior") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.Property<string>("Inputs") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.HasMaxLength(100) |
||||
|
.HasColumnType("varchar(100)"); |
||||
|
|
||||
|
b.Property<string>("Outputs") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<Guid?>("ParentId") |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.Property<TimeSpan?>("RetryInterval") |
||||
|
.HasColumnType("time(6)"); |
||||
|
|
||||
|
b.Property<bool>("Saga") |
||||
|
.HasColumnType("tinyint(1)"); |
||||
|
|
||||
|
b.Property<string>("SelectNextStep") |
||||
|
.HasColumnType("longtext"); |
||||
|
|
||||
|
b.Property<string>("StepType") |
||||
|
.HasMaxLength(100) |
||||
|
.HasColumnType("varchar(100)"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("TenantId"); |
||||
|
|
||||
|
b.Property<Guid>("WorkflowId") |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.ToTable("WF_Step", (string)null); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowManagement.Workflow", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.Property<string>("ConcurrencyStamp") |
||||
|
.IsConcurrencyToken() |
||||
|
.HasMaxLength(40) |
||||
|
.HasColumnType("varchar(40)") |
||||
|
.HasColumnName("ConcurrencyStamp"); |
||||
|
|
||||
|
b.Property<DateTime>("CreationTime") |
||||
|
.HasColumnType("datetime(6)") |
||||
|
.HasColumnName("CreationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("CreatorId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("CreatorId"); |
||||
|
|
||||
|
b.Property<string>("Description") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<string>("DisplayName") |
||||
|
.HasMaxLength(200) |
||||
|
.HasColumnType("varchar(200)"); |
||||
|
|
||||
|
b.Property<int>("ErrorBehavior") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.Property<TimeSpan?>("ErrorRetryInterval") |
||||
|
.HasColumnType("time(6)"); |
||||
|
|
||||
|
b.Property<string>("ExtraProperties") |
||||
|
.HasColumnType("longtext") |
||||
|
.HasColumnName("ExtraProperties"); |
||||
|
|
||||
|
b.Property<bool>("IsEnabled") |
||||
|
.HasColumnType("tinyint(1)"); |
||||
|
|
||||
|
b.Property<DateTime?>("LastModificationTime") |
||||
|
.HasColumnType("datetime(6)") |
||||
|
.HasColumnName("LastModificationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("LastModifierId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("LastModifierId"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(100) |
||||
|
.HasColumnType("varchar(100)"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("TenantId"); |
||||
|
|
||||
|
b.Property<int>("Version") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.ToTable("WF_Definition", (string)null); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowManagement.WorkflowData", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.Property<int>("DataType") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.Property<string>("DisplayName") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(100) |
||||
|
.HasColumnType("varchar(100)"); |
||||
|
|
||||
|
b.Property<bool>("IsCaseSensitive") |
||||
|
.HasColumnType("tinyint(1)"); |
||||
|
|
||||
|
b.Property<bool>("IsRequired") |
||||
|
.HasColumnType("tinyint(1)"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(100) |
||||
|
.HasColumnType("varchar(100)"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("TenantId"); |
||||
|
|
||||
|
b.Property<Guid>("WorkflowId") |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("WorkflowId"); |
||||
|
|
||||
|
b.ToTable("WF_DefinitionData", (string)null); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowCore.Persistence.PersistedExecutionPointer", b => |
||||
|
{ |
||||
|
b.HasOne("LINGYUN.Abp.WorkflowCore.Persistence.PersistedWorkflow", "Workflow") |
||||
|
.WithMany("ExecutionPointers") |
||||
|
.HasForeignKey("WorkflowId") |
||||
|
.OnDelete(DeleteBehavior.Cascade) |
||||
|
.IsRequired(); |
||||
|
|
||||
|
b.Navigation("Workflow"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowCore.Persistence.PersistedExtensionAttribute", b => |
||||
|
{ |
||||
|
b.HasOne("LINGYUN.Abp.WorkflowCore.Persistence.PersistedExecutionPointer", "ExecutionPointer") |
||||
|
.WithMany("ExtensionAttributes") |
||||
|
.HasForeignKey("ExecutionPointerId") |
||||
|
.OnDelete(DeleteBehavior.Cascade) |
||||
|
.IsRequired(); |
||||
|
|
||||
|
b.Navigation("ExecutionPointer"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowManagement.WorkflowData", b => |
||||
|
{ |
||||
|
b.HasOne("LINGYUN.Abp.WorkflowManagement.Workflow", null) |
||||
|
.WithMany("Datas") |
||||
|
.HasForeignKey("WorkflowId") |
||||
|
.OnDelete(DeleteBehavior.Cascade) |
||||
|
.IsRequired(); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowCore.Persistence.PersistedExecutionPointer", b => |
||||
|
{ |
||||
|
b.Navigation("ExtensionAttributes"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowCore.Persistence.PersistedWorkflow", b => |
||||
|
{ |
||||
|
b.Navigation("ExecutionPointers"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("LINGYUN.Abp.WorkflowManagement.Workflow", b => |
||||
|
{ |
||||
|
b.Navigation("Datas"); |
||||
|
}); |
||||
|
#pragma warning restore 612, 618
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,147 @@ |
|||||
|
using System; |
||||
|
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
|
||||
|
#nullable disable |
||||
|
|
||||
|
namespace LY.MicroService.WorkflowManagement.Migrations |
||||
|
{ |
||||
|
public partial class AddEntityWorkflowDataWithWFManagement : Migration |
||||
|
{ |
||||
|
protected override void Up(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.AlterColumn<Guid>( |
||||
|
name: "ExecutionPointerId", |
||||
|
table: "WF_Subscription", |
||||
|
type: "char(50)", |
||||
|
maxLength: 50, |
||||
|
nullable: false, |
||||
|
collation: "ascii_general_ci", |
||||
|
oldClrType: typeof(string), |
||||
|
oldType: "char(50)", |
||||
|
oldMaxLength: 50) |
||||
|
.OldAnnotation("MySql:CharSet", "utf8mb4"); |
||||
|
|
||||
|
migrationBuilder.AlterColumn<Guid>( |
||||
|
name: "ExecutionPointerId", |
||||
|
table: "WF_ExtensionAttribute", |
||||
|
type: "char(50)", |
||||
|
maxLength: 50, |
||||
|
nullable: false, |
||||
|
collation: "ascii_general_ci", |
||||
|
oldClrType: typeof(string), |
||||
|
oldType: "char(50)", |
||||
|
oldMaxLength: 50) |
||||
|
.OldAnnotation("MySql:CharSet", "utf8mb4"); |
||||
|
|
||||
|
migrationBuilder.AlterColumn<Guid>( |
||||
|
name: "Id", |
||||
|
table: "WF_ExecutionPointer", |
||||
|
type: "char(50)", |
||||
|
maxLength: 50, |
||||
|
nullable: false, |
||||
|
collation: "ascii_general_ci", |
||||
|
oldClrType: typeof(string), |
||||
|
oldType: "char(50)", |
||||
|
oldMaxLength: 50) |
||||
|
.OldAnnotation("MySql:CharSet", "utf8mb4"); |
||||
|
|
||||
|
migrationBuilder.AlterColumn<Guid>( |
||||
|
name: "ExecutionPointerId", |
||||
|
table: "WF_ExecutionError", |
||||
|
type: "char(50)", |
||||
|
maxLength: 50, |
||||
|
nullable: false, |
||||
|
collation: "ascii_general_ci", |
||||
|
oldClrType: typeof(string), |
||||
|
oldType: "char(50)", |
||||
|
oldMaxLength: 50) |
||||
|
.OldAnnotation("MySql:CharSet", "utf8mb4"); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "WF_DefinitionData", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"), |
||||
|
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
||||
|
WorkflowId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"), |
||||
|
Name = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: false) |
||||
|
.Annotation("MySql:CharSet", "utf8mb4"), |
||||
|
DisplayName = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: false) |
||||
|
.Annotation("MySql:CharSet", "utf8mb4"), |
||||
|
DataType = table.Column<int>(type: "int", nullable: false), |
||||
|
IsRequired = table.Column<bool>(type: "tinyint(1)", nullable: false), |
||||
|
IsCaseSensitive = table.Column<bool>(type: "tinyint(1)", nullable: false) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_WF_DefinitionData", x => x.Id); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_WF_DefinitionData_WF_Definition_WorkflowId", |
||||
|
column: x => x.WorkflowId, |
||||
|
principalTable: "WF_Definition", |
||||
|
principalColumn: "Id", |
||||
|
onDelete: ReferentialAction.Cascade); |
||||
|
}) |
||||
|
.Annotation("MySql:CharSet", "utf8mb4"); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_WF_DefinitionData_WorkflowId", |
||||
|
table: "WF_DefinitionData", |
||||
|
column: "WorkflowId"); |
||||
|
} |
||||
|
|
||||
|
protected override void Down(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.DropTable( |
||||
|
name: "WF_DefinitionData"); |
||||
|
|
||||
|
migrationBuilder.AlterColumn<string>( |
||||
|
name: "ExecutionPointerId", |
||||
|
table: "WF_Subscription", |
||||
|
type: "char(50)", |
||||
|
maxLength: 50, |
||||
|
nullable: false, |
||||
|
oldClrType: typeof(Guid), |
||||
|
oldType: "char(50)", |
||||
|
oldMaxLength: 50) |
||||
|
.Annotation("MySql:CharSet", "utf8mb4") |
||||
|
.OldAnnotation("Relational:Collation", "ascii_general_ci"); |
||||
|
|
||||
|
migrationBuilder.AlterColumn<string>( |
||||
|
name: "ExecutionPointerId", |
||||
|
table: "WF_ExtensionAttribute", |
||||
|
type: "char(50)", |
||||
|
maxLength: 50, |
||||
|
nullable: false, |
||||
|
oldClrType: typeof(Guid), |
||||
|
oldType: "char(50)", |
||||
|
oldMaxLength: 50) |
||||
|
.Annotation("MySql:CharSet", "utf8mb4") |
||||
|
.OldAnnotation("Relational:Collation", "ascii_general_ci"); |
||||
|
|
||||
|
migrationBuilder.AlterColumn<string>( |
||||
|
name: "Id", |
||||
|
table: "WF_ExecutionPointer", |
||||
|
type: "char(50)", |
||||
|
maxLength: 50, |
||||
|
nullable: false, |
||||
|
oldClrType: typeof(Guid), |
||||
|
oldType: "char(50)", |
||||
|
oldMaxLength: 50) |
||||
|
.Annotation("MySql:CharSet", "utf8mb4") |
||||
|
.OldAnnotation("Relational:Collation", "ascii_general_ci"); |
||||
|
|
||||
|
migrationBuilder.AlterColumn<string>( |
||||
|
name: "ExecutionPointerId", |
||||
|
table: "WF_ExecutionError", |
||||
|
type: "char(50)", |
||||
|
maxLength: 50, |
||||
|
nullable: false, |
||||
|
oldClrType: typeof(Guid), |
||||
|
oldType: "char(50)", |
||||
|
oldMaxLength: 50) |
||||
|
.Annotation("MySql:CharSet", "utf8mb4") |
||||
|
.OldAnnotation("Relational:Collation", "ascii_general_ci"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,18 +1,30 @@ |
|||||
using Microsoft.AspNetCore.Builder; |
using Microsoft.AspNetCore.Builder; |
||||
using Microsoft.Extensions.DependencyInjection; |
using Microsoft.Extensions.DependencyInjection; |
||||
|
using System.IO; |
||||
|
using Volo.Abp.IO; |
||||
|
using Volo.Abp.Modularity.PlugIns; |
||||
|
|
||||
namespace LY.MicroService.WorkflowManagement |
namespace LY.MicroService.WorkflowManagement; |
||||
|
|
||||
|
public class Startup |
||||
{ |
{ |
||||
public class Startup |
public void ConfigureServices(IServiceCollection services) |
||||
{ |
{ |
||||
public void ConfigureServices(IServiceCollection services) |
services.AddApplication<WorkflowManagementHttpApiHostModule>(options => |
||||
{ |
{ |
||||
services.AddApplication<WorkflowManagementHttpApiHostModule>(); |
// 搜索 Modules 目录下所有文件作为插件
|
||||
} |
// 取消显示引用所有其他项目的模块,改为通过插件的形式引用
|
||||
|
var pluginFolder = Path.Combine( |
||||
|
Directory.GetCurrentDirectory(), "Modules"); |
||||
|
DirectoryHelper.CreateIfNotExists(pluginFolder); |
||||
|
options.PlugInSources.AddFolder( |
||||
|
pluginFolder, |
||||
|
SearchOption.AllDirectories); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
public void Configure(IApplicationBuilder app) |
public void Configure(IApplicationBuilder app) |
||||
{ |
{ |
||||
app.InitializeApplication(); |
app.InitializeApplication(); |
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -1,18 +1,19 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFramework>net6.0</TargetFramework> |
<TargetFramework>net6.0</TargetFramework> |
||||
<RootNamespace /> |
<RootNamespace /> |
||||
<IsPackable>false</IsPackable> |
<IsPackable>false</IsPackable> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> |
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> |
||||
</ItemGroup> |
<!--<PackageReference Include="WorkflowCore.Testing" Version="3.5.2" />--> |
||||
|
</ItemGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="..\..\modules\workflow\LINGYUN.Abp.WorkflowCore\LINGYUN.Abp.WorkflowCore.csproj" /> |
<ProjectReference Include="..\..\modules\workflow\LINGYUN.Abp.WorkflowCore\LINGYUN.Abp.WorkflowCore.csproj" /> |
||||
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" /> |
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
@ -0,0 +1,72 @@ |
|||||
|
using Shouldly; |
||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using WorkflowCore.Interface; |
||||
|
using WorkflowCore.Models; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WorkflowCore.Middleware |
||||
|
{ |
||||
|
public class MultiTenancyStepMiddleware_Tests : AbpWorkflowCoreTestBase |
||||
|
{ |
||||
|
public static bool IsCompleted = false; |
||||
|
public static readonly Guid TenantId = Guid.NewGuid(); |
||||
|
private readonly IWorkflowController _controller; |
||||
|
public MultiTenancyStepMiddleware_Tests() |
||||
|
{ |
||||
|
_controller = GetRequiredService<IWorkflowController>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_Be_Resolved_Multi_Tenant_Id_On_Step() |
||||
|
{ |
||||
|
await _controller.StartWorkflow( |
||||
|
"MiddlewareWorkflow", |
||||
|
new MiddlewareWorkflowData |
||||
|
{ |
||||
|
TenantId = TenantId |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class MiddlewareWorkflowData : IMultiTenant |
||||
|
{ |
||||
|
public Guid? TenantId { get; set; } |
||||
|
} |
||||
|
|
||||
|
public class MiddlewareWorkflow : IWorkflow<MiddlewareWorkflowData> |
||||
|
{ |
||||
|
public string Id => "MiddlewareWorkflow"; |
||||
|
|
||||
|
public int Version => 1; |
||||
|
|
||||
|
public void Build(IWorkflowBuilder<MiddlewareWorkflowData> builder) |
||||
|
{ |
||||
|
builder.StartWith((_) => Console.WriteLine("Start Workflow")) |
||||
|
.Then<MessageStep>() |
||||
|
.Then((_) => MultiTenancyStepMiddleware_Tests.IsCompleted = true) |
||||
|
.EndWorkflow(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class MessageStep : StepBodyBase |
||||
|
{ |
||||
|
private readonly ICurrentTenant _currentTenant; |
||||
|
|
||||
|
public MessageStep(ICurrentTenant currentTenant) |
||||
|
{ |
||||
|
_currentTenant = currentTenant; |
||||
|
} |
||||
|
|
||||
|
public override ExecutionResult Run(IStepExecutionContext context) |
||||
|
{ |
||||
|
MultiTenancyStepMiddleware_Tests.TenantId.ShouldBe(_currentTenant.Id.Value); |
||||
|
|
||||
|
Console.WriteLine("Current Tenant Id: {0}", _currentTenant.Id?.ToString() ?? "Null"); |
||||
|
|
||||
|
return ExecutionResult.Next(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue