diff --git a/WorkFlowCore/Commons/Common.Authorization/User.cs b/WorkFlowCore/Commons/Common.Authorization/User.cs index 42472fbb42ce40fd149ba5a4d70ce681d4af28ba..759717b36981b1d504b9e443d9fbe54bf1a0002e 100644 --- a/WorkFlowCore/Commons/Common.Authorization/User.cs +++ b/WorkFlowCore/Commons/Common.Authorization/User.cs @@ -16,12 +16,18 @@ namespace Common.Authorization this.Name = handleUser_Name; } + public User(string id, string name, string tenantId) : this(id, name) + { + TenantId = tenantId; + } + public string Id { get; set; } public string Name { get; set; } + public string TenantId { get; set; } public override string ToString() { - return Id + "_" + Name; + return $"{TenantId}_{Id}_{Name}"; } } } diff --git a/WorkFlowCore/Commons/Common.BaseRepositories4EF/BaseRepositories4EFModule.cs b/WorkFlowCore/Commons/Common.BaseRepositories4EF/BaseRepositories4EFModule.cs index f2d3bd1da40ca89c0fe3984c9aba4c35a80b43d4..723208aca92d1acf078cce655940b27a1c48abcb 100644 --- a/WorkFlowCore/Commons/Common.BaseRepositories4EF/BaseRepositories4EFModule.cs +++ b/WorkFlowCore/Commons/Common.BaseRepositories4EF/BaseRepositories4EFModule.cs @@ -1,6 +1,8 @@ -using Common.IBaseRepositories; +using Common.BaseRepositories4EF.DbContexts; +using Common.IBaseRepositories; using Common.IBaseRepositories4EF; using Common.UnitOfWork4EntityFramework; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; @@ -18,5 +20,11 @@ namespace Common.BaseRepositories4EF services.AddUnitOfWork4EntityFramework(); return services; } + public static IServiceCollection AddCommonDbContext(this IServiceCollection services, Action options) where TDbContext : CommonDbContext + { + services.AddDbContext(); + DbContextConfigure.SetOptionsConfiguration(options); + return services; + } } } diff --git a/WorkFlowCore/Commons/Common.BaseRepositories4EF/BasicRepository4EF.cs b/WorkFlowCore/Commons/Common.BaseRepositories4EF/BasicRepository4EF.cs index 938b7743da3e4b9a4c99fc9e2c3b0379dde78224..0f724eff006e9b75e44676da92f6fc288526cb87 100644 --- a/WorkFlowCore/Commons/Common.BaseRepositories4EF/BasicRepository4EF.cs +++ b/WorkFlowCore/Commons/Common.BaseRepositories4EF/BasicRepository4EF.cs @@ -21,7 +21,7 @@ namespace Common.BaseRepositories4EF { public class BasicRepository4EF : IBasicRepository4EF where TEntity : class, IEntity { - private readonly DbContext dbContext; + protected readonly DbContext dbContext; private UnitOfWork4EF unitOfWork; private readonly ICommonSession session; @@ -41,8 +41,6 @@ namespace Common.BaseRepositories4EF if (entity != null) { unitOfWork.BeginWithoutLevel(); - - dbContext.Remove(entity); if (autoSave||!unitOfWork.IsActive()) await dbContext.SaveChangesAsync(); } @@ -65,7 +63,8 @@ namespace Common.BaseRepositories4EF if (cancellationToken != null && cancellationToken.IsCancellationRequested) return; - var entities = dbContext.Set().Where(t => ids.Contains(t.Id)).ToList(); + var queryable = dbContext.Set().Where(t => ids.Contains(t.Id)).AddTenantContition(session); + var entities = queryable.ToList(); if (entities != null) { unitOfWork.BeginWithoutLevel(); @@ -90,7 +89,8 @@ namespace Common.BaseRepositories4EF { if (cancellationToken != null && cancellationToken.IsCancellationRequested) return; - var entities = dbContext.Set().Where(predicate).ToList(); + var queryable = dbContext.Set().Where(predicate).AddTenantContition(session); + var entities = queryable.ToList(); if (entities != null) { unitOfWork.BeginWithoutLevel(); @@ -114,7 +114,8 @@ namespace Common.BaseRepositories4EF public async Task GetAsync([NotNull] Expression> predicate, bool includeDetails = false, CancellationToken cancellationToken = default) { if (cancellationToken != null && cancellationToken.IsCancellationRequested) return null; - return await Task.FromResult(dbContext.Set().Where(predicate).FirstOrDefault()); + var queryable = dbContext.Set().Where(predicate).AddTenantContition(session); + return await Task.FromResult(queryable.FirstOrDefault()); } public async Task GetCountAsync(CancellationToken cancellationToken = default) @@ -126,25 +127,26 @@ namespace Common.BaseRepositories4EF public async Task GetCountAsync([NotNull] Expression> predicate, CancellationToken cancellationToken = default) { if (cancellationToken != null && cancellationToken.IsCancellationRequested) return 0; - return await Task.FromResult(dbContext.Set().Count(predicate)); + var queryable = dbContext.Set().Where(predicate).AddTenantContition(session); + return await Task.FromResult(queryable.Count()); } public async Task> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default) { if (cancellationToken != null && cancellationToken.IsCancellationRequested) return null; - return await Task.FromResult(dbContext.Set().ToList()); + return await Task.FromResult(dbContext.Set().AddTenantContition(session).ToList()); } public async Task> GetListAsync([global::JetBrains.Annotations.NotNullAttribute] Expression> predicate, bool includeDetails = false, CancellationToken cancellationToken = default) { if (cancellationToken != null && cancellationToken.IsCancellationRequested) return null; - return await Task.FromResult(dbContext.Set().Where(predicate).ToList()); + return await Task.FromResult(dbContext.Set().Where(predicate).AddTenantContition(session).ToList()); } public async Task> GetPagedListAsync(int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default) { if (cancellationToken != null && cancellationToken.IsCancellationRequested) return null; - var query = dbContext.Set().Where(t => true); + var query = dbContext.Set().Where(t => true).AddTenantContition(session); if (!string.IsNullOrEmpty(sorting)) query = query.OrderBy(sorting); return await Task.FromResult(query.Skip(skipCount).Take(maxResultCount).ToList()); @@ -153,7 +155,7 @@ namespace Common.BaseRepositories4EF public async Task> GetPagedListAsync([NotNull] Expression> predicate, int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default) { if (cancellationToken != null && cancellationToken.IsCancellationRequested) return null; - var query = dbContext.Set().Where(predicate); + var query = dbContext.Set().Where(predicate).AddTenantContition(session); if (!string.IsNullOrEmpty(sorting)) query = query.OrderBy(sorting); return await Task.FromResult(query.Skip(skipCount).Take(maxResultCount).ToList()); @@ -172,7 +174,12 @@ namespace Common.BaseRepositories4EF withBaseInfoEntity.ModifiedUserId = session?.User?.Id; entity = (TEntity)withBaseInfoEntity; } - + if (entity is ITenantsEntity) + { + var tenantEntity = (ITenantsEntity)entity; + if (!string.IsNullOrEmpty(session?.User?.TenantId)) + tenantEntity.TenantId = session?.User?.TenantId; + } unitOfWork.BeginWithoutLevel(); await dbContext.Set().AddAsync(entity, cancellationToken); if (autoSave||!unitOfWork.IsActive()) await dbContext.SaveChangesAsync(cancellationToken); @@ -192,6 +199,12 @@ namespace Common.BaseRepositories4EF withBaseInfoEntity.ModifiedTime = DateTime.Now; withBaseInfoEntity.ModifiedUserId = session?.User?.Id; } + if (entity is ITenantsEntity) + { + var tenantEntity = (ITenantsEntity)entity; + if(!string.IsNullOrEmpty(session?.User?.TenantId)) + tenantEntity.TenantId = session?.User?.TenantId; + } } unitOfWork.BeginWithoutLevel(); await dbContext.Set().AddRangeAsync(entities, cancellationToken); @@ -206,6 +219,12 @@ namespace Common.BaseRepositories4EF withBaseInfoEntity.ModifiedTime = DateTime.Now; withBaseInfoEntity.ModifiedUserId = session?.User?.Id; } + if (entity is ITenantsEntity) + { + var tenantEntity = (ITenantsEntity)entity; + if (!string.IsNullOrEmpty(session?.User?.TenantId)) + tenantEntity.TenantId = session?.User?.TenantId; + } unitOfWork.BeginWithoutLevel(); dbContext.Set().Update(entity); if (autoSave || !unitOfWork.IsActive()) await dbContext.SaveChangesAsync(cancellationToken); @@ -223,6 +242,12 @@ namespace Common.BaseRepositories4EF withBaseInfoEntity.ModifiedTime = DateTime.Now; withBaseInfoEntity.ModifiedUserId = session?.User?.Id; } + if(entity is ITenantsEntity) + { + var tenantEntity = (ITenantsEntity)entity; + if (!string.IsNullOrEmpty(session?.User?.TenantId)) + tenantEntity.TenantId = session?.User?.TenantId; + } } unitOfWork.BeginWithoutLevel(); dbContext.Set().UpdateRange(entities); @@ -250,7 +275,7 @@ namespace Common.BaseRepositories4EF if (cancellationToken != null && cancellationToken.IsCancellationRequested) return null; - var query = dbContext.Set().Where(whereInfo.Where.ToString(), whereInfo.Parameters.ToArray()); + var query = dbContext.Set().Where(whereInfo.Where.ToString(), whereInfo.Parameters.ToArray()).AddTenantContition(session); if (predicate != null) query = query.Where(predicate); if (!string.IsNullOrEmpty(sorting)) query = query.OrderBy(sorting); @@ -261,7 +286,7 @@ namespace Common.BaseRepositories4EF { var whereInfo = QueryCondition.GetWhereInfo(conditions); if (cancellationToken != null && cancellationToken.IsCancellationRequested) return 0; - var query = dbContext.Set().Where(whereInfo.Where.ToString(), whereInfo.Parameters.ToArray()); + var query = dbContext.Set().Where(whereInfo.Where.ToString(), whereInfo.Parameters.ToArray()).AddTenantContition(session); if (predicate != null) query = query.Where(predicate); return query.Count(); } @@ -270,12 +295,123 @@ namespace Common.BaseRepositories4EF { var whereInfo = QueryCondition.GetWhereInfo(conditions); if (cancellationToken != null && cancellationToken.IsCancellationRequested) return null; - var query = dbContext.Set().Where(whereInfo.Where.ToString(), whereInfo.Parameters.ToArray()); + var query = dbContext.Set().Where(whereInfo.Where.ToString(), whereInfo.Parameters.ToArray()).AddTenantContition(session); if (predicate != null) query = query.Where(predicate); if (!string.IsNullOrEmpty(sorting)) query = query.OrderBy(sorting); return await Task.FromResult(query.Skip(skipCount).Take(maxResultCount).ToList()); } + + public async Task SoftDeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default) + { + if (cancellationToken != null && cancellationToken.IsCancellationRequested) return; + + var entity = await dbContext.Set().FindAsync(id); + if (entity != null) + { + if (entity is ISoftDeleteEntity) + { + var deleteEntity = (ISoftDeleteEntity)entity; + deleteEntity.DeletedUserId = session?.User?.Id; + deleteEntity.DeletedTime = DateTime.Now; + deleteEntity.Deleted = true; + } + unitOfWork.BeginWithoutLevel(); + dbContext.Update(entity); + if (autoSave || !unitOfWork.IsActive()) await dbContext.SaveChangesAsync(); + } + } + + public async Task SoftDeleteAsync([global::JetBrains.Annotations.NotNullAttribute] TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) + { + if (cancellationToken != null && cancellationToken.IsCancellationRequested) return; + + if (entity != null) + { + if (entity is ISoftDeleteEntity) + { + var deleteEntity = (ISoftDeleteEntity)entity; + deleteEntity.DeletedUserId = session?.User?.Id; + deleteEntity.DeletedTime = DateTime.Now; + deleteEntity.Deleted = true; + } + unitOfWork.BeginWithoutLevel(); + dbContext.Update(entity); + if (autoSave || !unitOfWork.IsActive()) await dbContext.SaveChangesAsync(cancellationToken); + } + } + + public async Task SoftDeleteManyAsync([global::JetBrains.Annotations.NotNullAttribute] IEnumerable ids, bool autoSave = false, CancellationToken cancellationToken = default) + { + + if (cancellationToken != null && cancellationToken.IsCancellationRequested) return; + + var entities = dbContext.Set().Where(t => ids.Contains(t.Id)).ToList(); + if (entities != null) + { + if (typeof(ISoftDeleteEntity).IsAssignableFrom(typeof(TEntity))) + { + foreach (var entity in entities) + { + var deleteEntity = (ISoftDeleteEntity)entity; + deleteEntity.DeletedUserId = session?.User?.Id; + deleteEntity.DeletedTime = DateTime.Now; + deleteEntity.Deleted = true; + } + } + unitOfWork.BeginWithoutLevel(); + dbContext.UpdateRange(entities); + if (autoSave || !unitOfWork.IsActive()) await dbContext.SaveChangesAsync(cancellationToken); + } + + } + + public async Task SoftDeleteManyAsync([global::JetBrains.Annotations.NotNullAttribute] IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default) + { + if (cancellationToken != null && cancellationToken.IsCancellationRequested) return; + if (entities != null) + { + if (typeof(ISoftDeleteEntity).IsAssignableFrom(typeof(TEntity))) + { + foreach (var entity in entities) + { + var deleteEntity = (ISoftDeleteEntity)entity; + deleteEntity.DeletedUserId = session?.User?.Id; + deleteEntity.DeletedTime = DateTime.Now; + deleteEntity.Deleted = true; + } + } + unitOfWork.BeginWithoutLevel(); + dbContext.UpdateRange(entities); + if (autoSave || !unitOfWork.IsActive()) await dbContext.SaveChangesAsync(cancellationToken); + } + } + + public async Task SoftDeleteManyAsync([NotNull] Expression> predicate, bool autoSave = false, CancellationToken cancellationToken = default) + { + if (cancellationToken != null && cancellationToken.IsCancellationRequested) return; + + var entities = dbContext.Set().Where(predicate).AddTenantContition(session).ToList(); + if (entities != null) + { + if (typeof(ISoftDeleteEntity).IsAssignableFrom(typeof(TEntity))) + { + foreach (var entity in entities) + { + var deleteEntity = (ISoftDeleteEntity)entity; + deleteEntity.DeletedUserId = session?.User?.Id; + deleteEntity.DeletedTime = DateTime.Now; + deleteEntity.Deleted = true; + } + } + unitOfWork.BeginWithoutLevel(); + dbContext.UpdateRange(entities); + if (autoSave || !unitOfWork.IsActive()) await dbContext.SaveChangesAsync(cancellationToken); + } + } + + + } public class BasicRepository4EF : BasicRepository4EF, IReadOnlyBasicRepository where TEntity : class, IEntity diff --git a/WorkFlowCore/Commons/Common.BaseRepositories4EF/DbContexts/CommonDbContext.cs b/WorkFlowCore/Commons/Common.BaseRepositories4EF/DbContexts/CommonDbContext.cs new file mode 100644 index 0000000000000000000000000000000000000000..e80180e62de953bbefc6f7c8fb5cb529ea07da12 --- /dev/null +++ b/WorkFlowCore/Commons/Common.BaseRepositories4EF/DbContexts/CommonDbContext.cs @@ -0,0 +1,31 @@ +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.BaseRepositories4EF.DbContexts +{ + public class CommonDbContext : DbContext + { + public CommonDbContext([NotNull] DbContextOptions options) : base(options) + { + } + static int index = 0; + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + var configuration = DbContextConfigure.GetOptionsConfiguration(this.GetType()); + if (configuration != null) + { + var isDynamicConnect = index % 2 == 0; + //TODO 根据当前会话获取租户信息,多租户的 host 自己根据需要配置是否分库,原则上, + var commonConfigure = new CommonDbContextOptionsBuilder(isDynamicConnect, "", ""); + index++; + configuration.Invoke(commonConfigure); + if(commonConfigure.Options!=null&&(isDynamicConnect || !optionsBuilder.IsConfigured)) + commonConfigure.Options.Invoke(optionsBuilder); + } + base.OnConfiguring(optionsBuilder); + } + } +} diff --git a/WorkFlowCore/Commons/Common.BaseRepositories4EF/DbContexts/CommonDbContextOptionsBuilder.cs b/WorkFlowCore/Commons/Common.BaseRepositories4EF/DbContexts/CommonDbContextOptionsBuilder.cs new file mode 100644 index 0000000000000000000000000000000000000000..ccc0d18d39ed563d889ce1f2003941adbf229761 --- /dev/null +++ b/WorkFlowCore/Commons/Common.BaseRepositories4EF/DbContexts/CommonDbContextOptionsBuilder.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.BaseRepositories4EF.DbContexts +{ + public class CommonDbContextOptionsBuilder + { + public CommonDbContextOptionsBuilder(bool isDynamicConnect, string connectionString, string connectionVersion) + { + IsDynamicConnect = isDynamicConnect; + ConnectionString = connectionString; + ConnectionVersion = connectionVersion; + + } + + public void ConfigureDbContext(Action options) + { + Options = options; + } + + public bool IsDynamicConnect { get;internal set; } + public string ConnectionString { get;internal set; } + public string ConnectionVersion { get;internal set; } + public Action Options { get;set; } + } +} diff --git a/WorkFlowCore/Commons/Common.BaseRepositories4EF/DbContexts/DbContextConfigure.cs b/WorkFlowCore/Commons/Common.BaseRepositories4EF/DbContexts/DbContextConfigure.cs new file mode 100644 index 0000000000000000000000000000000000000000..8727ccf9e59b1b8d2a59be128263484780d869ca --- /dev/null +++ b/WorkFlowCore/Commons/Common.BaseRepositories4EF/DbContexts/DbContextConfigure.cs @@ -0,0 +1,30 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.BaseRepositories4EF.DbContexts +{ + internal static class DbContextConfigure + { + private static Dictionary> contextConfigurations; + static DbContextConfigure() + { + contextConfigurations = new Dictionary>(); + } + + internal static Action GetOptionsConfiguration(Type typeOfDbContext) + { + if(contextConfigurations.ContainsKey(typeOfDbContext)) + return contextConfigurations[typeOfDbContext]; + return null; + } + internal static void SetOptionsConfiguration(Action action) where TDbContext : CommonDbContext + { + if (contextConfigurations.ContainsKey(typeof(TDbContext))) + contextConfigurations[typeof(TDbContext)] = action; + else contextConfigurations.Add(typeof(TDbContext), action); + } + + } +} diff --git a/WorkFlowCore/Commons/Common.BaseRepositories4EF/EfContextExtensions.cs b/WorkFlowCore/Commons/Common.BaseRepositories4EF/EfContextExtensions.cs new file mode 100644 index 0000000000000000000000000000000000000000..4af10838e5fff3cc75c5e894db1cdd8a203d8897 --- /dev/null +++ b/WorkFlowCore/Commons/Common.BaseRepositories4EF/EfContextExtensions.cs @@ -0,0 +1,25 @@ +using Common.Authorization; +using Common.IBaseRepositories; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Text; + +namespace Common.BaseRepositories4EF +{ + public static class EfContextExtensions + { + public static IQueryable AddTenantContition(this IQueryable queryable, ICommonSession session) where TEntity : class, IEntity + { + if (typeof(ITenantsEntity).IsAssignableFrom(typeof(TEntity))) + { + if (!string.IsNullOrEmpty(session?.User?.TenantId)) + { + queryable = queryable.Where("TenantId={0}", session?.User?.TenantId); + } + } + return queryable; + } + } +} diff --git a/WorkFlowCore/Commons/Common.DynamicApi/DynamicApiBuilderModule.cs b/WorkFlowCore/Commons/Common.DynamicApi/DynamicApiBuilderModule.cs index 178c4a4cb32a64e82b6d69e191c9e1431b7a8b26..77e46eb69cefed4d185663ccd6f1a6aa698dbef5 100644 --- a/WorkFlowCore/Commons/Common.DynamicApi/DynamicApiBuilderModule.cs +++ b/WorkFlowCore/Commons/Common.DynamicApi/DynamicApiBuilderModule.cs @@ -17,7 +17,7 @@ namespace Common.DynamicApi services.AddControllers(options => { //全局异常过滤 - options.Filters.Add(); + //options.Filters.Add(); }).AddDynamicApi(appServiceAassembly); services.AddScoped(); diff --git a/WorkFlowCore/Commons/Common.DynamicApi/DynamicApiInterceptors/UnitOfWorkApiInterceptor.cs b/WorkFlowCore/Commons/Common.DynamicApi/DynamicApiInterceptors/UnitOfWorkApiInterceptor.cs index cfe1783a9d0748691862672755377ee54af439a3..27677cfa1b9cfcc99172725720e3f5255fb5867c 100644 --- a/WorkFlowCore/Commons/Common.DynamicApi/DynamicApiInterceptors/UnitOfWorkApiInterceptor.cs +++ b/WorkFlowCore/Commons/Common.DynamicApi/DynamicApiInterceptors/UnitOfWorkApiInterceptor.cs @@ -21,6 +21,7 @@ namespace Common.DynamicApi.DynamicApiInterceptors public void BeforeExecute() { // + //unitOfWork.Enabled(); } public void Executed() diff --git a/WorkFlowCore/Commons/Common.EventBus.Kafka/IKafkaEventBus.cs b/WorkFlowCore/Commons/Common.EventBus.Kafka/IKafkaEventBus.cs new file mode 100644 index 0000000000000000000000000000000000000000..dbd4c6cd5ef7897320de821c3c1dd724aa06ec3e --- /dev/null +++ b/WorkFlowCore/Commons/Common.EventBus.Kafka/IKafkaEventBus.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.EventBus.Kafka +{ + public interface IKafkaEventBus: IEventBus + { + } +} diff --git a/WorkFlowCore/Commons/Common.EventBus.Kafka/KafkaEventBus.cs b/WorkFlowCore/Commons/Common.EventBus.Kafka/KafkaEventBus.cs index 2c2ffbcedd03b3546c3be372f6345e763877244b..a44db002c25ee69e8248c9f8f6c4a248b1b10e5d 100644 --- a/WorkFlowCore/Commons/Common.EventBus.Kafka/KafkaEventBus.cs +++ b/WorkFlowCore/Commons/Common.EventBus.Kafka/KafkaEventBus.cs @@ -13,7 +13,7 @@ using System.Threading.Tasks; namespace Common.EventBus.Kafka { - public class KafkaEventBus : IEventBus + public class KafkaEventBus : IKafkaEventBus { private IServiceProvider serviceProvider; private readonly KafkaEventConfig eventConfig; @@ -92,13 +92,22 @@ namespace Common.EventBus.Kafka var data = JsonConvert.DeserializeObject(cr.Message.Value, eventDataType); using (var scope = serviceProvider.CreateScope()) { - var handler = scope.ServiceProvider.GetService(handlerType); - handlerType.GetMethod("Handle", new Type[] { eventDataType }).Invoke(handler, new object[] { data }); //统一工作单元提交,无需事件单独处理 var unitOfWork = scope.ServiceProvider.GetService(); - + var handler = scope.ServiceProvider.GetService(handlerType); + try + { + handlerType.GetMethod("Handle", new Type[] { eventDataType }).Invoke(handler, new object[] { data }); + unitOfWork.Commit(); + } + catch (Exception ex) + { + logger.LogError(ex, "kafka事件异常"); + unitOfWork.Rollback(); + } + var domainEventBusService = scope.ServiceProvider.GetService(); - if (unitOfWork == null || unitOfWork.Commit()) domainEventBusService?.Trigger(); + if (unitOfWork == null || unitOfWork.HasCommitted()) domainEventBusService?.Trigger(); } c.Commit(cr); diff --git a/WorkFlowCore/Commons/Common.EventBus.Kafka/KafkaEventBusModule.cs b/WorkFlowCore/Commons/Common.EventBus.Kafka/KafkaEventBusModule.cs index 70660f138c23dc7ab371ed2a02deab4065863f9c..431e5efab2e889e9bed0e5aced9a61d9dd5dfa41 100644 --- a/WorkFlowCore/Commons/Common.EventBus.Kafka/KafkaEventBusModule.cs +++ b/WorkFlowCore/Commons/Common.EventBus.Kafka/KafkaEventBusModule.cs @@ -11,6 +11,7 @@ namespace Common.EventBus.Kafka { public static IServiceCollection AddKafkaEventBus(this IServiceCollection services, Action options) { + services.AddSingleton(typeof(IKafkaEventBus), typeof(KafkaEventBus)); services.AddSingleton(typeof(IEventBus), typeof(KafkaEventBus)); services.AddSingleton(typeof(KafkaEventBus)); var config = new KafkaEventConfig(); diff --git a/WorkFlowCore/Commons/Common.EventBus.Repository4EF/Common.EventBus.Repository4EF.csproj b/WorkFlowCore/Commons/Common.EventBus.Repository4EF/Common.EventBus.Repository4EF.csproj new file mode 100644 index 0000000000000000000000000000000000000000..0e2b6a94b4048f92639a317d33208facaf53a2dd --- /dev/null +++ b/WorkFlowCore/Commons/Common.EventBus.Repository4EF/Common.EventBus.Repository4EF.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp3.1 + + + + + + + + + + + + diff --git a/WorkFlowCore/Commons/Common.EventBus.Repository4EF/CommonEventBusRepository4EFModule.cs b/WorkFlowCore/Commons/Common.EventBus.Repository4EF/CommonEventBusRepository4EFModule.cs new file mode 100644 index 0000000000000000000000000000000000000000..96953cf3f749be7155f8afa0454a35708bcd5f3f --- /dev/null +++ b/WorkFlowCore/Commons/Common.EventBus.Repository4EF/CommonEventBusRepository4EFModule.cs @@ -0,0 +1,20 @@ +using Common.EventBus.IRepositories; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.EventBus.Repository4EF +{ + public static class CommonEventBusRepository4EFModule + { + public static IServiceCollection AddEventBusRepository4EF(this IServiceCollection services)where IDbContext: DbContext,IEventBusDbContext + { + services.AddScoped(); + return services; + } + + + } +} diff --git a/WorkFlowCore/Commons/Common.EventBus.Repository4EF/EventData.cs b/WorkFlowCore/Commons/Common.EventBus.Repository4EF/EventData.cs new file mode 100644 index 0000000000000000000000000000000000000000..92d319d93661929ea7cba24d7095466299cc18b0 --- /dev/null +++ b/WorkFlowCore/Commons/Common.EventBus.Repository4EF/EventData.cs @@ -0,0 +1,34 @@ +using Common.IBaseRepositories; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Common.EventBus.Repository4EF +{ + public class EventData : IRepositories.EventData, IEntity, ICreationEntity,ITenantsEntity + { + public EventData() + { + } + public EventData(IRepositories.EventData data) + { + Publisher = data.Publisher; + PublishId = data.PublishId; + PublishTime = data.PublishTime; + IsRePublish = data.IsRePublish; + EventContent = data.EventContent; + CreationTime = DateTime.Now; + } + + public string CreatedUserId { get; set; } + public DateTime CreationTime { get; set; } + public string TenantId { get; set; } + public long Id { get; set; } + + public object[] GetKeys() + { + return GetType().GetProperties().Select(p => p.Name).ToArray(); + } + } +} diff --git a/WorkFlowCore/Commons/Common.EventBus.Repository4EF/EventDataRepository.cs b/WorkFlowCore/Commons/Common.EventBus.Repository4EF/EventDataRepository.cs new file mode 100644 index 0000000000000000000000000000000000000000..9e8b65925f1b509ea887e15f101cb9c051071b43 --- /dev/null +++ b/WorkFlowCore/Commons/Common.EventBus.Repository4EF/EventDataRepository.cs @@ -0,0 +1,26 @@ +using Common.EventBus.IRepositories; +using Common.IBaseRepositories; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Common.EventBus.Repository4EF +{ + public class EventDataRepository : IEventDataRepository + { + private readonly IBasicRepository basicRepository; + + public EventDataRepository(IBaseRepositories.IBasicRepository basicRepository) + { + this.basicRepository = basicRepository; + } + + public Task InsertAsync(IRepositories.EventData eventData, CancellationToken cancellationToken = default) + { + var eventDataEntity = new EventData(eventData); + return basicRepository.InsertAsync(eventDataEntity); + } + } +} diff --git a/WorkFlowCore/Commons/Common.EventBus.Repository4EF/IEventBusDbContext.cs b/WorkFlowCore/Commons/Common.EventBus.Repository4EF/IEventBusDbContext.cs new file mode 100644 index 0000000000000000000000000000000000000000..cca5fcc3cb54657c5d34f106d8e050792bffd7df --- /dev/null +++ b/WorkFlowCore/Commons/Common.EventBus.Repository4EF/IEventBusDbContext.cs @@ -0,0 +1,12 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.EventBus.Repository4EF +{ + public interface IEventBusDbContext + { + DbSet CommonEventDatas { get; set; } + } +} diff --git a/WorkFlowCore/Commons/Common.EventBus/CommonEventBusConfig.cs b/WorkFlowCore/Commons/Common.EventBus/CommonEventBusConfig.cs new file mode 100644 index 0000000000000000000000000000000000000000..ec769451ca12879e48bbc62857373760135a038c --- /dev/null +++ b/WorkFlowCore/Commons/Common.EventBus/CommonEventBusConfig.cs @@ -0,0 +1,16 @@ +using Common.EventBus.IRepositories; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.EventBus +{ + public class CommonEventBusConfig + { + internal Type EventDataRepositoryType; + public void ReEventDataRepository()where TEventDataRepository : IEventDataRepository + { + EventDataRepositoryType = typeof(IEventDataRepository); + } + } +} diff --git a/WorkFlowCore/Commons/Common.EventBus/CommonEventBusModule.cs b/WorkFlowCore/Commons/Common.EventBus/CommonEventBusModule.cs new file mode 100644 index 0000000000000000000000000000000000000000..7fc358e3c4956056d47004b91e56e28b272468b9 --- /dev/null +++ b/WorkFlowCore/Commons/Common.EventBus/CommonEventBusModule.cs @@ -0,0 +1,26 @@ +using Common.EventBus.IRepositories; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.EventBus +{ + public static class CommonEventBusModule + { + //public static IServiceCollection AddEventBus(this IServiceCollection services,Action options=null ) + //{ + // if(options==null)return services; + + // var config = new CommonEventBusConfig(); + // options.Invoke(config); + // if(config.EventDataRepositoryType!=null) + // { + // services.AddScoped(typeof(IEventDataRepository), config.EventDataRepositoryType); + // } + // return services; + //} + + + } +} diff --git a/WorkFlowCore/Commons/Common.EventBus/DomainEventBusManager.cs b/WorkFlowCore/Commons/Common.EventBus/DomainEventBusManager.cs index 6f8554f6ec320c1feaf2cf10b465bcfa31a56eed..e4bc2445924947f4db20b3838657a8fd16c8745a 100644 --- a/WorkFlowCore/Commons/Common.EventBus/DomainEventBusManager.cs +++ b/WorkFlowCore/Commons/Common.EventBus/DomainEventBusManager.cs @@ -8,7 +8,7 @@ namespace Common.EventBus /// /// 全局静态事件帮助类,便于在其它非注入渠道发起事件 /// - public class DomainEventBusManager + internal class DomainEventBusManager { private static IServiceProvider serviceProvider; internal static void Init(IServiceProvider serviceProvider) diff --git a/WorkFlowCore/Commons/Common.EventBus/DomainEventBusService.cs b/WorkFlowCore/Commons/Common.EventBus/DomainEventBusService.cs index fd36434df63ed9a2336bf9a0049c1a5bbfa4be47..fcec2713451f3d168f449971aef6c2ee178ff143 100644 --- a/WorkFlowCore/Commons/Common.EventBus/DomainEventBusService.cs +++ b/WorkFlowCore/Commons/Common.EventBus/DomainEventBusService.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using Common.EventBus.IRepositories; +using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Text; @@ -9,17 +10,21 @@ namespace Common.EventBus { private readonly IServiceProvider serviceProvider; private List baseEventDatas; + private readonly IEventDataRepository eventDataRepository; public DomainEventBusService(IServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; baseEventDatas = new List(); + this.eventDataRepository = serviceProvider.GetService(); } public void Publish(TData data) where TData : BaseEventData { if (data == null) return; - //TODO 保存到数据库 + //保存到数据库 + if (eventDataRepository != null) + eventDataRepository.InsertAsync(EventData.CreateEventData(data)); baseEventDatas.Add(data); } public void Trigger() diff --git a/WorkFlowCore/Commons/Common.EventBus/IRepositories/EventData.cs b/WorkFlowCore/Commons/Common.EventBus/IRepositories/EventData.cs new file mode 100644 index 0000000000000000000000000000000000000000..802874993eb19da76850712569268ed33b0d1d83 --- /dev/null +++ b/WorkFlowCore/Commons/Common.EventBus/IRepositories/EventData.cs @@ -0,0 +1,30 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.EventBus.IRepositories +{ + public class EventData + { + public static EventData CreateEventData(BaseEventData data) + { + var eventData = new EventData(); + eventData.Publisher = data.Publisher; + eventData.PublishId = data.PublishId; + eventData.PublishTime = data.PublishTime; + eventData.IsRePublish = data.IsRePublish; + eventData.EventContent = JsonConvert.SerializeObject(data); + return eventData; + } + + public string Publisher { get; set; } + public Guid PublishId { get; set; } + public DateTime PublishTime { get; set; } + public bool IsRePublish { get; set; } + /// + /// json序列化数据 + /// + public string EventContent { get; set; } + } +} diff --git a/WorkFlowCore/Commons/Common.EventBus/IRepositories/IEventDataRepository.cs b/WorkFlowCore/Commons/Common.EventBus/IRepositories/IEventDataRepository.cs new file mode 100644 index 0000000000000000000000000000000000000000..6e36cdc6a5766595c263a610303299828aae325d --- /dev/null +++ b/WorkFlowCore/Commons/Common.EventBus/IRepositories/IEventDataRepository.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Common.EventBus.IRepositories +{ + public interface IEventDataRepository + { + Task InsertAsync(EventData eventData, CancellationToken cancellationToken = default); + } +} diff --git a/WorkFlowCore/Commons/Common.IBaseRepositories/ICreationEntity.cs b/WorkFlowCore/Commons/Common.IBaseRepositories/ICreationEntity.cs new file mode 100644 index 0000000000000000000000000000000000000000..d3edf35d76ca8c602521e0639b665eb39e2b88dd --- /dev/null +++ b/WorkFlowCore/Commons/Common.IBaseRepositories/ICreationEntity.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.IBaseRepositories +{ + public interface ICreationEntity + { + /// + /// 创建用户 + /// + string CreatedUserId { get; set; } + /// + /// 创建时间 + /// + DateTime CreationTime { get; set; } + } +} diff --git a/WorkFlowCore/Commons/Common.IBaseRepositories/IModificationEntity.cs b/WorkFlowCore/Commons/Common.IBaseRepositories/IModificationEntity.cs new file mode 100644 index 0000000000000000000000000000000000000000..77b4fd0959b42d085864f9acadedece265bcf3c9 --- /dev/null +++ b/WorkFlowCore/Commons/Common.IBaseRepositories/IModificationEntity.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.IBaseRepositories +{ + public interface IModificationEntity + { + /// + /// 更新时间 + /// + DateTime ModifiedTime { get; set; } + /// + /// 更新用户 + /// + string ModifiedUserId { get; set; } + } +} diff --git a/WorkFlowCore/Commons/Common.IBaseRepositories/ISoftDeleteEntity.cs b/WorkFlowCore/Commons/Common.IBaseRepositories/ISoftDeleteEntity.cs new file mode 100644 index 0000000000000000000000000000000000000000..bad794d32186cc0bf20ba454c79480fa280c0142 --- /dev/null +++ b/WorkFlowCore/Commons/Common.IBaseRepositories/ISoftDeleteEntity.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.IBaseRepositories +{ + public interface ISoftDeleteEntity + { + /// + /// 删除用户 + /// + string DeletedUserId { get; set; } + /// + /// 删除时间 + /// + DateTime DeletedTime { get; set; } + /// + /// 删除状态 + /// + bool Deleted { get; set; } + } +} diff --git a/WorkFlowCore/Commons/Common.IBaseRepositories/ISoftDeleteRepository.cs b/WorkFlowCore/Commons/Common.IBaseRepositories/ISoftDeleteRepository.cs new file mode 100644 index 0000000000000000000000000000000000000000..383d015e288d72711b9846f9f1abf15b268e5f08 --- /dev/null +++ b/WorkFlowCore/Commons/Common.IBaseRepositories/ISoftDeleteRepository.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using JetBrains.Annotations; +using System.Linq.Expressions; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Common.IBaseRepositories +{ + public interface ISoftDeleteRepository where TEntity : class, IEntity + { + /// + /// Deletes an entity. + /// + /// Entity to be deleted + /// + /// Set true to automatically save changes to database. + /// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database. + /// + /// A to observe while waiting for the task to complete. + Task SoftDeleteAsync([NotNull] TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default); + + /// + /// Deletes multiple entities. + /// + /// Entities to be deleted. + /// + /// Set true to automatically save changes to database. + /// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database. + /// + /// A to observe while waiting for the task to complete. + /// Awaitable . + Task SoftDeleteManyAsync([NotNull] IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default); + + /// + /// Deletes multiple entities. + /// + /// conditions + /// + /// Set true to automatically save changes to database. + /// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database. + /// + /// A to observe while waiting for the task to complete. + /// + Task SoftDeleteManyAsync([NotNull] Expression> predicate, bool autoSave = false, CancellationToken cancellationToken = default); +} + + public interface ISoftDeleteRepository where TEntity : class, IEntity + { + /// + /// Deletes an entity by primary key. + /// + /// Primary key of the entity + /// + /// Set true to automatically save changes to database. + /// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database. + /// + /// A to observe while waiting for the task to complete. + Task SoftDeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default); //TODO: Return true if deleted + + /// + /// Deletes multiple entities by primary keys. + /// + /// Primary keys of the each entity. + /// + /// Set true to automatically save changes to database. + /// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database. + /// + /// A to observe while waiting for the task to complete. + /// Awaitable . + Task SoftDeleteManyAsync([NotNull] IEnumerable ids, bool autoSave = false, CancellationToken cancellationToken = default); + } +} diff --git a/WorkFlowCore/Commons/Common.IBaseRepositories/ITenantsEntity.cs b/WorkFlowCore/Commons/Common.IBaseRepositories/ITenantsEntity.cs new file mode 100644 index 0000000000000000000000000000000000000000..a614979572d41ad4a6a598cc8ad97597bdeb42c8 --- /dev/null +++ b/WorkFlowCore/Commons/Common.IBaseRepositories/ITenantsEntity.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.IBaseRepositories +{ + public interface ITenantsEntity + { + public string TenantId { get; set; } + } +} diff --git a/WorkFlowCore/Commons/Common.IBaseRepositories/IWithBaseInfoEntity.cs b/WorkFlowCore/Commons/Common.IBaseRepositories/IWithBaseInfoEntity.cs index e78e1610bec1221cbd348c1069df2b04f158f89a..34fa2e8f5d9aa838187085ead5e73b14b0d34cea 100644 --- a/WorkFlowCore/Commons/Common.IBaseRepositories/IWithBaseInfoEntity.cs +++ b/WorkFlowCore/Commons/Common.IBaseRepositories/IWithBaseInfoEntity.cs @@ -5,37 +5,12 @@ using System.Text; namespace Common.IBaseRepositories { - public interface IWithBaseInfoEntity : IEntity + public interface IWithBaseInfoEntity : IEntity,ICreationEntity,IModificationEntity, ISoftDeleteEntity { - /// - /// 更新时间 - /// - DateTime ModifiedTime { get; set; } - /// - /// 更新用户 - /// - string ModifiedUserId { get; set; } - /// - /// 创建用户 - /// - string CreatedUserId { get; set; } - /// - /// 创建时间 - /// - DateTime CreationTime { get; set; } + + - /// - /// 删除用户 - /// - string DeletedUserId { get; set; } - /// - /// 删除时间 - /// - DateTime DeletedTime { get; set; } - /// - /// 删除状态 - /// - bool Deleted { get; set; } + } public interface IWithBaseInfoEntity : IWithBaseInfoEntity diff --git a/WorkFlowCore/Commons/Common.IBaseRepositories4EF/IBasicRepository4EF.cs b/WorkFlowCore/Commons/Common.IBaseRepositories4EF/IBasicRepository4EF.cs index 20ccaea450cd3a65b86849cbfb441e599cabd4bf..ca5d75d3b5aada925a3129fe2ca1fe0dd5776636 100644 --- a/WorkFlowCore/Commons/Common.IBaseRepositories4EF/IBasicRepository4EF.cs +++ b/WorkFlowCore/Commons/Common.IBaseRepositories4EF/IBasicRepository4EF.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace Common.IBaseRepositories4EF { - public interface IBasicRepository4EF : IBasicRepository, IReadOnlyBasicRepository where TEntity : class, IEntity + public interface IBasicRepository4EF : IBasicRepository, IReadOnlyBasicRepository, ISoftDeleteRepository where TEntity : class, IEntity { Task> GetListAsync( List conditions, diff --git a/WorkFlowCore/Commons/Common.Mapster/Common.Mapster.csproj b/WorkFlowCore/Commons/Common.Mapster/Common.Mapster.csproj new file mode 100644 index 0000000000000000000000000000000000000000..83e07b160d7739054f73017810c15d0d3833e5ac --- /dev/null +++ b/WorkFlowCore/Commons/Common.Mapster/Common.Mapster.csproj @@ -0,0 +1,12 @@ + + + + netcoreapp3.1 + + + + + + + + diff --git a/WorkFlowCore/Commons/Common.Mapster/CommonMapsterModule.cs b/WorkFlowCore/Commons/Common.Mapster/CommonMapsterModule.cs new file mode 100644 index 0000000000000000000000000000000000000000..1734712da21353a84f1f25b89d24ba4f8f68e42f --- /dev/null +++ b/WorkFlowCore/Commons/Common.Mapster/CommonMapsterModule.cs @@ -0,0 +1,58 @@ +using Mapster; +using MapsterMapper; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace Common.Mapster +{ + public static class CommonMapsterModule + { + private static TypeAdapterConfig config = new TypeAdapterConfig();//放外面声明可以多次调用注册 + public static IServiceCollection AddMapster(this IServiceCollection services,params Assembly[] assemblies) + { + if(assemblies!=null) + { + //扫描 register + config.Scan(assemblies); + //扫描自定义特性 + foreach(Assembly assembly in assemblies) + { + var types = assembly.GetTypes(); + foreach(Type type in types) + { + var mapfromAttrs = type.GetCustomAttributes(); + if(mapfromAttrs != null) + { + foreach (var item in mapfromAttrs) + { + if (item.FromType == null) continue; + config.ForType(item.FromType, type); + } + } + + var maptoAttrs = type.GetCustomAttributes(); + if (maptoAttrs != null) + { + foreach (var item in maptoAttrs) + { + if (item.ToType == null) continue; + config.ForType(type, item.ToType); + } + } + } + } + + } + + var mapper = new Mapper(config);//务必设置为单实例 + services.AddSingleton(mapper); + services.AddSingleton(serviceProvider=>mapper); + + return services; + } + } +} diff --git a/WorkFlowCore/Commons/Common.Mapster/MapFromAttribute.cs b/WorkFlowCore/Commons/Common.Mapster/MapFromAttribute.cs new file mode 100644 index 0000000000000000000000000000000000000000..e58856979a5bc13856865fa573441810941bb912 --- /dev/null +++ b/WorkFlowCore/Commons/Common.Mapster/MapFromAttribute.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.Mapster +{ + [AttributeUsage(AttributeTargets.Class)] + public class MapFromAttribute : Attribute + { + public Type FromType; + public MapFromAttribute(Type FromType) + { + this.FromType = FromType; + } + } +} diff --git a/WorkFlowCore/Commons/Common.Mapster/MapToAttribute.cs b/WorkFlowCore/Commons/Common.Mapster/MapToAttribute.cs new file mode 100644 index 0000000000000000000000000000000000000000..d15ab2808f50df966d5c01e847ae4e13523ba7b6 --- /dev/null +++ b/WorkFlowCore/Commons/Common.Mapster/MapToAttribute.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Common.Mapster +{ + [AttributeUsage(AttributeTargets.Class)] + public class MapToAttribute : Attribute + { + public Type ToType; + public MapToAttribute(Type ToType) + { + this.ToType = ToType; + } + } +} diff --git a/WorkFlowCore/Commons/Common.MicroService/Registers/Consul.cs b/WorkFlowCore/Commons/Common.MicroService/Registers/Consul.cs index 5ee1bb79041f870a8cad8aa77d2e35f87da8f735..5123d9003355bf95577da2d425bbb3dc76825b29 100644 --- a/WorkFlowCore/Commons/Common.MicroService/Registers/Consul.cs +++ b/WorkFlowCore/Commons/Common.MicroService/Registers/Consul.cs @@ -4,7 +4,9 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using System; using System.Collections.Generic; +using System.Net.NetworkInformation; using System.Text; +using System.Linq; namespace Common.MicroService.Registers { @@ -18,7 +20,7 @@ namespace Common.MicroService.Registers public string ServicePort { get; set; } public string ServiceName { get; set; } } - public static void RunConsulRegister(this IApplicationBuilder app,Actionoptions, IHostApplicationLifetime hostApplicationLifetime) + public static void RunConsulRegister(this IApplicationBuilder app, Action options, IHostApplicationLifetime hostApplicationLifetime) { var _options = new RegisterOptions(); options?.Invoke(_options); @@ -37,27 +39,40 @@ namespace Common.MicroService.Registers var port = _options.ServicePort; var serviceName = _options.ServiceName; Console.WriteLine($"args:{ip},{port},{serviceName}"); - var registration = new AgentServiceRegistration() + + + var addresses = NetworkInterface.GetAllNetworkInterfaces() + .Select(i => i.GetIPProperties()) + .Select(i => i.UnicastAddresses); + + foreach (var localAddresses in addresses) { - ID = serviceName + "-" + Guid.NewGuid(), - Name = serviceName, - Address = ip, - Port = int.Parse(port), - Check = new AgentServiceCheck + foreach (var localAddress in localAddresses) { - Interval = TimeSpan.FromSeconds(10), - HTTP = $"http://{ip}:{port}/api/Health/", - Timeout = TimeSpan.FromSeconds(5), - DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(30) - } - }; + var ipAddress = localAddress.Address.ToString(); + var registration = new AgentServiceRegistration() + { + ID = serviceName + "-" + Guid.NewGuid(), + Name = serviceName, + Address = ipAddress, + Port = int.Parse(port), + Check = new AgentServiceCheck + { + Interval = TimeSpan.FromSeconds(10), + HTTP = $"http://{ipAddress}:{port}/api/Health/", + Timeout = TimeSpan.FromSeconds(5), + DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(30) + } + }; - client.Agent.ServiceRegister(registration); + client.Agent.ServiceRegister(registration); - hostApplicationLifetime.ApplicationStopped.Register(() => - { - client.Agent.ServiceDeregister(registration.ID); - }); + hostApplicationLifetime.ApplicationStopped.Register(() => + { + client.Agent.ServiceDeregister(registration.ID); + }); + } + } } } } diff --git a/WorkFlowCore/Commons/Common.SimplePluginLoader/Common.SimplePluginLoader.csproj b/WorkFlowCore/Commons/Common.SimplePluginLoader/Common.SimplePluginLoader.csproj new file mode 100644 index 0000000000000000000000000000000000000000..9a58a1dde3fa6ea016409bcff3b021e73689cc75 --- /dev/null +++ b/WorkFlowCore/Commons/Common.SimplePluginLoader/Common.SimplePluginLoader.csproj @@ -0,0 +1,14 @@ + + + + netcoreapp3.1 + disable + enable + + + + + + + + diff --git a/WorkFlowCore/Commons/Common.SimplePluginLoader/CommonSimplePluginLoader.cs b/WorkFlowCore/Commons/Common.SimplePluginLoader/CommonSimplePluginLoader.cs new file mode 100644 index 0000000000000000000000000000000000000000..1d280e46e23d06393e4f208866426991f9644118 --- /dev/null +++ b/WorkFlowCore/Commons/Common.SimplePluginLoader/CommonSimplePluginLoader.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Text; +using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json; + +namespace Common.SimplePluginLoader +{ + public static class CommonSimplePluginLoader + { + /// + /// 载入插件 + /// + /// + /// + /// + /// + /// + public static IServiceCollection LoadPlugins(this IServiceCollection services, string pluginDir, Action> loaded) where TManifest : Manifest + { + if (!Directory.Exists(pluginDir)) return services; + + var plugins = new List(); + + var dirs = Directory.GetDirectories(pluginDir); + foreach (var dir in dirs) + { + var manifestPath = Path.Combine(dir, "manifest.json"); + if (!File.Exists(manifestPath)) continue; + try + { + var manifest = JsonConvert.DeserializeObject(File.ReadAllText(manifestPath)); + if (manifest == null) continue; + + var context = new PluginAssemblyLoadContext(System.IO.Path.Combine(dir, "src", manifest.Entry)); + var EntryLib = manifest.Entry; + var assembly = context.LoadFromAssemblyName(new System.Reflection.AssemblyName(EntryLib.Substring(0, EntryLib.Length - 4))); + manifest.Assembly = assembly; + plugins.Add(manifest); + } + catch (Exception ex) + { + + // + } + + } + loaded?.Invoke(plugins); + + return services; + } + + public static IServiceCollection LoadPlugins(this IServiceCollection services, string pluginDir, Action> loaded) + { + return LoadPlugins(services, pluginDir, loaded); + } + } +} diff --git a/WorkFlowCore/Commons/Common.SimplePluginLoader/Manifest.cs b/WorkFlowCore/Commons/Common.SimplePluginLoader/Manifest.cs new file mode 100644 index 0000000000000000000000000000000000000000..adbbfad34c9851c89d6524d24bd2963731dba494 --- /dev/null +++ b/WorkFlowCore/Commons/Common.SimplePluginLoader/Manifest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; + +namespace Common.SimplePluginLoader +{ + public class Manifest + { + public string Entry { get; set; } + public string Version { get; set; } + public Assembly Assembly { get; set; } + } +} diff --git a/WorkFlowCore/Commons/Common.SimplePluginLoader/PluginAssemblyLoadContext.cs b/WorkFlowCore/Commons/Common.SimplePluginLoader/PluginAssemblyLoadContext.cs new file mode 100644 index 0000000000000000000000000000000000000000..7d8a31557f684ec32feb277064278598004b637b --- /dev/null +++ b/WorkFlowCore/Commons/Common.SimplePluginLoader/PluginAssemblyLoadContext.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Loader; +using System.Text; + +namespace Common.SimplePluginLoader +{ + public class PluginAssemblyLoadContext : AssemblyLoadContext + { + private AssemblyDependencyResolver _resolver; + + public PluginAssemblyLoadContext(string mainAssemblyToLoadPath) : base(isCollectible: true) + { + _resolver = new AssemblyDependencyResolver(mainAssemblyToLoadPath); + } + + protected override Assembly Load(AssemblyName name) + { + string assemblyPath = _resolver.ResolveAssemblyToPath(name); + if (assemblyPath != null) + { + return LoadFromAssemblyPath(assemblyPath); + } + + return null; + } + } +} diff --git a/WorkFlowCore/Commons/Common.UnitOfWork/IUnitOfWork.cs b/WorkFlowCore/Commons/Common.UnitOfWork/IUnitOfWork.cs index 9498982c963c6e2046ba03130a75eaa9914071d2..8ddd63f62b915421f21029c3ea4405758ebfefbe 100644 --- a/WorkFlowCore/Commons/Common.UnitOfWork/IUnitOfWork.cs +++ b/WorkFlowCore/Commons/Common.UnitOfWork/IUnitOfWork.cs @@ -8,6 +8,7 @@ namespace Common.UnitOfWork { bool Commit(); + void Rollback(); bool HasCommitted(); bool IsActive(); void Enabled(); diff --git a/WorkFlowCore/Commons/Common.UnitOfWork/UnitOfWorkMiddleware.cs b/WorkFlowCore/Commons/Common.UnitOfWork/UnitOfWorkMiddleware.cs index f9a46b3c0170a54350e21514c723c326a5e16dff..8d3be38534e1870fae5f59af5b07d7496713e430 100644 --- a/WorkFlowCore/Commons/Common.UnitOfWork/UnitOfWorkMiddleware.cs +++ b/WorkFlowCore/Commons/Common.UnitOfWork/UnitOfWorkMiddleware.cs @@ -19,7 +19,15 @@ namespace Common.UnitOfWork { unitOfWork.Enabled(); - await next(context); + try + { + await next(context); + } + catch (Exception) + { + unitOfWork.Rollback(); + throw; + } unitOfWork.Commit(); } } diff --git a/WorkFlowCore/Commons/Common.UnitOfWork4EntityFramework/UnitOfWork4EF.cs b/WorkFlowCore/Commons/Common.UnitOfWork4EntityFramework/UnitOfWork4EF.cs index 978658abca5a8b9d9f338e36b0329b535a1f8ba5..0ecada50a6ff097193c930c57cc4ecd5a842e607 100644 --- a/WorkFlowCore/Commons/Common.UnitOfWork4EntityFramework/UnitOfWork4EF.cs +++ b/WorkFlowCore/Commons/Common.UnitOfWork4EntityFramework/UnitOfWork4EF.cs @@ -46,7 +46,7 @@ namespace Common.UnitOfWork4EntityFramework { Console.WriteLine(ex.ToString()); //回滚 - dbContextTransaction.Rollback(); + Rollback(); return false; } @@ -54,8 +54,10 @@ namespace Common.UnitOfWork4EntityFramework public void Dispose() { - if(isActive) - Commit(); + if (dbContextTransaction == null) return; + + //if (isActive) + // Commit(); if (!isActive) dbContextTransaction?.Dispose(); } @@ -91,5 +93,12 @@ namespace Common.UnitOfWork4EntityFramework { return isEnabled&&hasCommitted; } + + public void Rollback() + { + //回滚 + dbContextTransaction.Rollback(); + isActive = false; + } } } diff --git a/WorkFlowCore/Commons/Common.WebApi/Common.WebApi.csproj b/WorkFlowCore/Commons/Common.WebApi/Common.WebApi.csproj index f2730a36824af748a962050191a743a51bdefe5b..0340a10ffaa3891736820b85c712706effeee124 100644 --- a/WorkFlowCore/Commons/Common.WebApi/Common.WebApi.csproj +++ b/WorkFlowCore/Commons/Common.WebApi/Common.WebApi.csproj @@ -13,6 +13,7 @@ + diff --git a/WorkFlowCore/Commons/Common.WebApi/ExceptionMiddleware.cs b/WorkFlowCore/Commons/Common.WebApi/ExceptionMiddleware.cs new file mode 100644 index 0000000000000000000000000000000000000000..ba7557ef617d742d04835ff67531add3d21eed42 --- /dev/null +++ b/WorkFlowCore/Commons/Common.WebApi/ExceptionMiddleware.cs @@ -0,0 +1,39 @@ +using Common.UnitOfWork; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using System.Net; +using Newtonsoft.Json; +using Common.WebApi.ViewModels; + +namespace Common.WebApi +{ + public class ExceptionMiddleware + { + private readonly RequestDelegate next; + + public ExceptionMiddleware( RequestDelegate next) + { + this.next = next; + } + + public async Task Invoke(HttpContext context,ILogger logger) + { + try + { + await next(context); + } + catch (Exception ex) + { + context.Response.ContentType="application/json"; + context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; + context.Response.Body.WriteAsync(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(OutputDto.Failed($"发生异常:{ex.Message}")))); + logger.LogError($"发生异常:{ex.Message}", ex); + Console.Error.WriteLine(ex.ToString()); + } + } + } +} diff --git a/WorkFlowCore/Commons/Common.WebApi/WebApiModule.cs b/WorkFlowCore/Commons/Common.WebApi/WebApiModule.cs new file mode 100644 index 0000000000000000000000000000000000000000..423b285a0d4a81f74b5aa24b69dce7c5d6a2aa84 --- /dev/null +++ b/WorkFlowCore/Commons/Common.WebApi/WebApiModule.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Builder; + +namespace Common.WebApi +{ + public static class WebApiModule + { + public static IApplicationBuilder UseWebApiExceptionHandler(this IApplicationBuilder app) + { + app.UseMiddleware(); + return app; + + } + } +} diff --git a/WorkFlowCore/DynamicForm/DynamicForm.AppService/DynamicFormAppModule.cs b/WorkFlowCore/DynamicForm/DynamicForm.AppService/DynamicFormAppModule.cs index 701d0ee26fafc2ea4093a2147baeabdde168c0a9..4751d0cbb6ad79a55e74171910eff82189767d6c 100644 --- a/WorkFlowCore/DynamicForm/DynamicForm.AppService/DynamicFormAppModule.cs +++ b/WorkFlowCore/DynamicForm/DynamicForm.AppService/DynamicFormAppModule.cs @@ -3,8 +3,10 @@ using Common.DynamicApi; using Common.EventBus; using Common.EventBus.Default; using Common.EventBus.Kafka; +using Common.Mapster; using Common.MicroService.Registers; using DynamicForm.Core; +using DynamicForm.IAppService; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -22,9 +24,9 @@ namespace DynamicForm.AppService { var serviceConfig = new DynamicFormAppModuleConfiguration(services); options?.Invoke(serviceConfig); - + services.AddMapster(Assembly.GetExecutingAssembly()); + services.AddDynamicFormAppContracts(); services.AddDependencyServices(Assembly.GetExecutingAssembly()); - services.AddDefautEventBus(Assembly.GetExecutingAssembly(), typeof(DynamicFormCoreModule).Assembly); services.AddKafkaEventBus(config => { @@ -44,12 +46,6 @@ namespace DynamicForm.AppService { this.services = services; } - - public void AddDynamicControllers() - { - services.AddDynamicControllers(Assembly.GetExecutingAssembly()); - } - /// /// kafka连接地址配置 /// diff --git a/WorkFlowCore/DynamicForm/DynamicForm.Framework/DynamicForm.Framework.csproj b/WorkFlowCore/DynamicForm/DynamicForm.Framework/DynamicForm.Framework.csproj index 7e17f71c2a595350f14bb46a077bc18eeb84e078..403de920644546a83225633f165ac7f37e7442e0 100644 --- a/WorkFlowCore/DynamicForm/DynamicForm.Framework/DynamicForm.Framework.csproj +++ b/WorkFlowCore/DynamicForm/DynamicForm.Framework/DynamicForm.Framework.csproj @@ -12,6 +12,7 @@ + diff --git a/WorkFlowCore/DynamicForm/DynamicForm.Framework/DynamicFormDbContext.cs b/WorkFlowCore/DynamicForm/DynamicForm.Framework/DynamicFormDbContext.cs index c33586b388c2055f44cd8fbe7b3f7062a35012ea..98adcce6d1406348783cccda97558ccb918c0559 100644 --- a/WorkFlowCore/DynamicForm/DynamicForm.Framework/DynamicFormDbContext.cs +++ b/WorkFlowCore/DynamicForm/DynamicForm.Framework/DynamicFormDbContext.cs @@ -1,4 +1,6 @@ -using DynamicForm.Core; +using Common.BaseRepositories4EF.DbContexts; +using Common.EventBus.Repository4EF; +using DynamicForm.Core; using DynamicForm.Core.Users; using DynamicForm.Core.Workflows; using JetBrains.Annotations; @@ -12,7 +14,7 @@ using System.Threading.Tasks; namespace DynamicForm.Framework { - public class DynamicFormDbContext : DbContext + public class DynamicFormDbContext : CommonDbContext, IEventBusDbContext { public DynamicFormDbContext([JetBrains.Annotations.NotNull] DbContextOptions options) : base(options) { @@ -29,6 +31,15 @@ namespace DynamicForm.Framework #region 工作流 public DbSet WorkflowVersions { get; set; } #endregion + /// + /// 公共事件数据 + /// + public DbSet CommonEventDatas { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + base.OnConfiguring(optionsBuilder); + } protected override void OnModelCreating(ModelBuilder modelBuilder) { diff --git a/WorkFlowCore/DynamicForm/DynamicForm.Framework/DynamicFormFrameworkModule.cs b/WorkFlowCore/DynamicForm/DynamicForm.Framework/DynamicFormFrameworkModule.cs index 331a925781aea44e1d5a14d682aaf3de79c3a165..f30a9648e42d3b3c91f5881730d0a90fad6f3a4a 100644 --- a/WorkFlowCore/DynamicForm/DynamicForm.Framework/DynamicFormFrameworkModule.cs +++ b/WorkFlowCore/DynamicForm/DynamicForm.Framework/DynamicFormFrameworkModule.cs @@ -1,6 +1,7 @@ using Common.Authorization; using Common.BaseRepositories4EF; using Common.DependencyInjection; +using Common.EventBus.Repository4EF; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using System; @@ -22,12 +23,27 @@ namespace DynamicForm.Framework var configuration = new DynamicFormFrameworkModuleConfiguration(); options?.Invoke(configuration); + /*services.AddDbContext()*/; + //services.AddDbContext(op => + //{ + // op.UseMySql(configuration?.DbConnectionString, new MySqlServerVersion(configuration.DbServerVersion)); + //}); - services.AddDbContext(op => + services.AddCommonDbContext(options => { - op.UseMySql(configuration?.DbConnectionString, new MySqlServerVersion(configuration.DbServerVersion)); + // + options.ConfigureDbContext(op => + { + if (options.IsDynamicConnect) + op.UseMySql(configuration?.DbConnectionString, new MySqlServerVersion(configuration.DbServerVersion)); + else + op.UseMySql(configuration?.DbConnectionString, new MySqlServerVersion(configuration.DbServerVersion)); + }); }); services.AddScoped(); + + //注册事件仓储 + services.AddEventBusRepository4EF(); return services; } diff --git a/WorkFlowCore/DynamicForm/DynamicForm.Framework/Migrations/20221022025345_addeventdata.Designer.cs b/WorkFlowCore/DynamicForm/DynamicForm.Framework/Migrations/20221022025345_addeventdata.Designer.cs new file mode 100644 index 0000000000000000000000000000000000000000..2d6b610f1db22b8b371985c65859d01d4967438f --- /dev/null +++ b/WorkFlowCore/DynamicForm/DynamicForm.Framework/Migrations/20221022025345_addeventdata.Designer.cs @@ -0,0 +1,294 @@ +// +using System; +using DynamicForm.Framework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace DynamicForm.Framework.Migrations +{ + [DbContext(typeof(DynamicFormDbContext))] + [Migration("20221022025345_addeventdata")] + partial class addeventdata + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 64) + .HasAnnotation("ProductVersion", "5.0.13"); + + modelBuilder.Entity("Common.EventBus.Repository4EF.EventData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("EventContent") + .HasColumnType("longtext"); + + b.Property("IsRePublish") + .HasColumnType("bit(1)"); + + b.Property("PublishId") + .HasColumnType("char(36)"); + + b.Property("PublishTime") + .HasColumnType("datetime(6)"); + + b.Property("Publisher") + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("CommonEventDatas"); + }); + + modelBuilder.Entity("DynamicForm.Core.FormDesignInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ActiveVersion") + .HasColumnType("int"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("FormType") + .HasColumnType("longtext"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("WorkflowId_Id") + .HasColumnType("char(36)"); + + b.Property("WorkflowId_Version") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("FormDesignInfos"); + }); + + modelBuilder.Entity("DynamicForm.Core.FormDesignVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("DesignContent") + .HasColumnType("longtext"); + + b.Property("FormDesignId") + .HasColumnType("char(36)"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("Version") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("FormDesignVersions"); + }); + + modelBuilder.Entity("DynamicForm.Core.FormInstanceInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CurrentHandleInfo_NodeName") + .HasColumnType("longtext"); + + b.Property("CurrentHandleInfo_StepId") + .HasColumnType("longtext"); + + b.Property("CurrentHandleInfo_UserId") + .HasColumnType("longtext"); + + b.Property("CurrentHandleInfo_UserName") + .HasColumnType("longtext"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("FormData") + .HasColumnType("longtext"); + + b.Property("FormDesignId_Id") + .HasColumnType("char(36)"); + + b.Property("FormDesignId_Version") + .HasColumnType("int"); + + b.Property("LatestProveData") + .HasColumnType("longtext"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("WorkflowId_Id") + .HasColumnType("char(36)"); + + b.Property("WorkflowId_Version") + .HasColumnType("int"); + + b.Property("WorkflowStatus") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("FormInstanceInfos"); + }); + + modelBuilder.Entity("DynamicForm.Core.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("DynamicForm_User"); + }); + + modelBuilder.Entity("DynamicForm.Core.Workflows.WorkflowVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("VersionNo") + .HasColumnType("int"); + + b.Property("WorkflowId") + .HasColumnType("char(36)"); + + b.Property("WorkflowName") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("DynamicForm_WorkflowVersion"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/WorkFlowCore/DynamicForm/DynamicForm.Framework/Migrations/20221022025345_addeventdata.cs b/WorkFlowCore/DynamicForm/DynamicForm.Framework/Migrations/20221022025345_addeventdata.cs new file mode 100644 index 0000000000000000000000000000000000000000..51d10de2d3ee77ff36cec96b4bdb248255e63cfb --- /dev/null +++ b/WorkFlowCore/DynamicForm/DynamicForm.Framework/Migrations/20221022025345_addeventdata.cs @@ -0,0 +1,43 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace DynamicForm.Framework.Migrations +{ + public partial class addeventdata : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "CommonEventDatas", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CreatedUserId = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + CreationTime = table.Column(type: "datetime(6)", nullable: false), + TenantId = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Publisher = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + PublishId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + PublishTime = table.Column(type: "datetime(6)", nullable: false), + IsRePublish = table.Column(type: "bit(1)", nullable: false), + EventContent = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_CommonEventDatas", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CommonEventDatas"); + } + } +} diff --git a/WorkFlowCore/DynamicForm/DynamicForm.Framework/Migrations/DynamicFormDbContextModelSnapshot.cs b/WorkFlowCore/DynamicForm/DynamicForm.Framework/Migrations/DynamicFormDbContextModelSnapshot.cs index 5b9c6376090be4876a7aeab4e2e56714d538836a..7b0beb7dd98138fe220489f2e32488bdb1da94ef 100644 --- a/WorkFlowCore/DynamicForm/DynamicForm.Framework/Migrations/DynamicFormDbContextModelSnapshot.cs +++ b/WorkFlowCore/DynamicForm/DynamicForm.Framework/Migrations/DynamicFormDbContextModelSnapshot.cs @@ -1,7 +1,9 @@ // using System; +using DynamicForm.Framework; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace DynamicForm.Framework.Migrations { @@ -15,6 +17,41 @@ namespace DynamicForm.Framework.Migrations .HasAnnotation("Relational:MaxIdentifierLength", 64) .HasAnnotation("ProductVersion", "5.0.13"); + modelBuilder.Entity("Common.EventBus.Repository4EF.EventData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("EventContent") + .HasColumnType("longtext"); + + b.Property("IsRePublish") + .HasColumnType("bit(1)"); + + b.Property("PublishId") + .HasColumnType("char(36)"); + + b.Property("PublishTime") + .HasColumnType("datetime(6)"); + + b.Property("Publisher") + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("CommonEventDatas"); + }); + modelBuilder.Entity("DynamicForm.Core.FormDesignInfo", b => { b.Property("Id") diff --git a/WorkFlowCore/DynamicForm/DynamicForm.Host/Startup.cs b/WorkFlowCore/DynamicForm/DynamicForm.Host/Startup.cs index e1715d014d7f20f66fe11bc943fcabc1b70c71fb..215ad4b4dae8dbdf6b482768896615f16dc35663 100644 --- a/WorkFlowCore/DynamicForm/DynamicForm.Host/Startup.cs +++ b/WorkFlowCore/DynamicForm/DynamicForm.Host/Startup.cs @@ -1,9 +1,11 @@ using Common.BackgroundWorker; +using Common.DynamicApi; using Common.EventBus; using Common.EventBus.Kafka; using Common.MicroService.Registers; using Common.UnitOfWork; +using Common.WebApi; using DynamicForm.AppService; using DynamicForm.Core; using DynamicForm.Framework; @@ -48,11 +50,12 @@ namespace DynamicForm.Host services.AddDynamicFormApp(options => { - options.AddDynamicControllers(); options.KafkaBootstrapServers = Configuration.GetValueFromManyChanels("Kafka:BootstrapServers"); - }); + services.AddDynamicControllers(typeof(DynamicFormAppModule).Assembly); + + services.AddDynamicFormCore(options => { options.MicroServiceGateway = Configuration.GetValueFromManyChanels("Gateway"); @@ -106,8 +109,10 @@ namespace DynamicForm.Host app.UseAuthorization(); app.UseEventBus(); app.RunKafkaEventBus(); + + app.UseWebApiExceptionHandler(); + app.UseUnitOfWork(); - app.UseEndpoints(endpoints => { endpoints.MapControllers(); diff --git a/WorkFlowCore/DynamicForm/DynamicForm.IAppService/DynamicForm.IAppService.csproj b/WorkFlowCore/DynamicForm/DynamicForm.IAppService/DynamicForm.IAppService.csproj index 10e2bc242d455754007571eddcd461e8826d1f9c..3d3381f8c283aaa1e43273ccffcbbf56518d5e84 100644 --- a/WorkFlowCore/DynamicForm/DynamicForm.IAppService/DynamicForm.IAppService.csproj +++ b/WorkFlowCore/DynamicForm/DynamicForm.IAppService/DynamicForm.IAppService.csproj @@ -6,6 +6,7 @@ + diff --git a/WorkFlowCore/DynamicForm/DynamicForm.IAppService/DynamicFormAppContractsModule.cs b/WorkFlowCore/DynamicForm/DynamicForm.IAppService/DynamicFormAppContractsModule.cs new file mode 100644 index 0000000000000000000000000000000000000000..4e1ca5de912b711af58907ce86acc3382c279bfc --- /dev/null +++ b/WorkFlowCore/DynamicForm/DynamicForm.IAppService/DynamicFormAppContractsModule.cs @@ -0,0 +1,17 @@ + +using Microsoft.Extensions.DependencyInjection; +using System.Reflection; +using System.Text; +using Common.Mapster; + +namespace DynamicForm.IAppService +{ + public static class DynamicFormAppContractsModule + { + public static IServiceCollection AddDynamicFormAppContracts(this IServiceCollection services) + { + services.AddMapster(Assembly.GetExecutingAssembly()); + return services; + } + } +} diff --git a/WorkFlowCore/UserOrganization/Organization.AppService/OrganizationAppModule.cs b/WorkFlowCore/UserOrganization/Organization.AppService/OrganizationAppModule.cs index 4855a9591542729aa35943262a7ffdc61155a36a..5a3a5b9d34b06d53988168b040603f1e18fde189 100644 --- a/WorkFlowCore/UserOrganization/Organization.AppService/OrganizationAppModule.cs +++ b/WorkFlowCore/UserOrganization/Organization.AppService/OrganizationAppModule.cs @@ -3,8 +3,10 @@ using Common.DynamicApi; using Common.EventBus; using Common.EventBus.Default; using Common.EventBus.Kafka; +using Common.Mapster; using Microsoft.Extensions.DependencyInjection; using Organization.Core; +using Organization.IAppService; using System; using System.Collections.Generic; using System.Linq; @@ -21,9 +23,9 @@ namespace Organization.AppService var serviceConfig = new OrganizationAppModuleConfiguration(services); options?.Invoke(serviceConfig); + services.AddMapster(Assembly.GetExecutingAssembly()); + services.AddOrganizationAppContracts(); services.AddDependencyServices(Assembly.GetExecutingAssembly()); - - services.AddDefautEventBus(Assembly.GetExecutingAssembly(), typeof(OrganizationCoreModule).Assembly); services.AddKafkaEventBus(config => @@ -43,10 +45,6 @@ namespace Organization.AppService this.services = services; } - public void AddDynamicControllers() - { - services.AddDynamicControllers(Assembly.GetExecutingAssembly()); - } /// /// kafka连接地址配置 /// diff --git a/WorkFlowCore/UserOrganization/Organization.Framework/Migrations/20221022025952_addeventdata.Designer.cs b/WorkFlowCore/UserOrganization/Organization.Framework/Migrations/20221022025952_addeventdata.Designer.cs new file mode 100644 index 0000000000000000000000000000000000000000..a2568a43beea1b29cf65e23c3b045caee7f74ab9 --- /dev/null +++ b/WorkFlowCore/UserOrganization/Organization.Framework/Migrations/20221022025952_addeventdata.Designer.cs @@ -0,0 +1,270 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Organization.Framework; + +namespace Organization.Framework.Migrations +{ + [DbContext(typeof(OrganizationDbContext))] + [Migration("20221022025952_addeventdata")] + partial class addeventdata + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 64) + .HasAnnotation("ProductVersion", "5.0.13"); + + modelBuilder.Entity("Common.EventBus.Repository4EF.EventData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("EventContent") + .HasColumnType("longtext"); + + b.Property("IsRePublish") + .HasColumnType("bit(1)"); + + b.Property("PublishId") + .HasColumnType("char(36)"); + + b.Property("PublishTime") + .HasColumnType("datetime(6)"); + + b.Property("Publisher") + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("CommonEventDatas"); + }); + + modelBuilder.Entity("Organization.Core.Organizations.Organization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Code") + .HasColumnType("longtext"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("FullName") + .HasColumnType("longtext"); + + b.Property("MaxNum") + .HasColumnType("int"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("PreCode") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Organizations"); + }); + + modelBuilder.Entity("Organization.Core.Organizations.UserOrganization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("IsLeader") + .HasColumnType("bit(1)"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("OrganizationCode") + .HasColumnType("longtext"); + + b.Property("OrganizationName") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("UserName") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("UserOrganization"); + }); + + modelBuilder.Entity("Organization.Core.Roles.UserRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("RoleName") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("UserName") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("UserRoles"); + }); + + modelBuilder.Entity("Organization.Core.Users.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("Organization.Core.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("Email") + .HasColumnType("longtext"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/WorkFlowCore/UserOrganization/Organization.Framework/Migrations/20221022025952_addeventdata.cs b/WorkFlowCore/UserOrganization/Organization.Framework/Migrations/20221022025952_addeventdata.cs new file mode 100644 index 0000000000000000000000000000000000000000..5c20c11ecfb956ff45ce3a77b689a8106ce45e22 --- /dev/null +++ b/WorkFlowCore/UserOrganization/Organization.Framework/Migrations/20221022025952_addeventdata.cs @@ -0,0 +1,43 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Organization.Framework.Migrations +{ + public partial class addeventdata : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "CommonEventDatas", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CreatedUserId = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + CreationTime = table.Column(type: "datetime(6)", nullable: false), + TenantId = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Publisher = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + PublishId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + PublishTime = table.Column(type: "datetime(6)", nullable: false), + IsRePublish = table.Column(type: "bit(1)", nullable: false), + EventContent = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_CommonEventDatas", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CommonEventDatas"); + } + } +} diff --git a/WorkFlowCore/UserOrganization/Organization.Framework/Migrations/OrganizationDbContextModelSnapshot.cs b/WorkFlowCore/UserOrganization/Organization.Framework/Migrations/OrganizationDbContextModelSnapshot.cs index 18d36d7b890617989b7f85fc3d9bf2008f96030f..20aec0d91aaa2deab2f9b9d796df8046d090ea74 100644 --- a/WorkFlowCore/UserOrganization/Organization.Framework/Migrations/OrganizationDbContextModelSnapshot.cs +++ b/WorkFlowCore/UserOrganization/Organization.Framework/Migrations/OrganizationDbContextModelSnapshot.cs @@ -17,6 +17,41 @@ namespace Organization.Framework.Migrations .HasAnnotation("Relational:MaxIdentifierLength", 64) .HasAnnotation("ProductVersion", "5.0.13"); + modelBuilder.Entity("Common.EventBus.Repository4EF.EventData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("EventContent") + .HasColumnType("longtext"); + + b.Property("IsRePublish") + .HasColumnType("bit(1)"); + + b.Property("PublishId") + .HasColumnType("char(36)"); + + b.Property("PublishTime") + .HasColumnType("datetime(6)"); + + b.Property("Publisher") + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("CommonEventDatas"); + }); + modelBuilder.Entity("Organization.Core.Organizations.Organization", b => { b.Property("Id") @@ -111,7 +146,7 @@ namespace Organization.Framework.Migrations b.ToTable("UserOrganization"); }); - modelBuilder.Entity("Organization.Core.Users.Role", b => + modelBuilder.Entity("Organization.Core.Roles.UserRole", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -138,15 +173,24 @@ namespace Organization.Framework.Migrations b.Property("ModifiedUserId") .HasColumnType("longtext"); - b.Property("Name") + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("RoleName") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("UserName") .HasColumnType("longtext"); b.HasKey("Id"); - b.ToTable("Roles"); + b.ToTable("UserRoles"); }); - modelBuilder.Entity("Organization.Core.Users.User", b => + modelBuilder.Entity("Organization.Core.Users.Role", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -167,9 +211,6 @@ namespace Organization.Framework.Migrations b.Property("DeletedUserId") .HasColumnType("longtext"); - b.Property("Email") - .HasColumnType("longtext"); - b.Property("ModifiedTime") .HasColumnType("datetime(6)"); @@ -181,10 +222,10 @@ namespace Organization.Framework.Migrations b.HasKey("Id"); - b.ToTable("Users"); + b.ToTable("Roles"); }); - modelBuilder.Entity("Organization.Core.Users.UserRole", b => + modelBuilder.Entity("Organization.Core.Users.User", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -205,27 +246,21 @@ namespace Organization.Framework.Migrations b.Property("DeletedUserId") .HasColumnType("longtext"); + b.Property("Email") + .HasColumnType("longtext"); + b.Property("ModifiedTime") .HasColumnType("datetime(6)"); b.Property("ModifiedUserId") .HasColumnType("longtext"); - b.Property("RoleId") - .HasColumnType("char(36)"); - - b.Property("RoleName") - .HasColumnType("longtext"); - - b.Property("UserId") - .HasColumnType("char(36)"); - - b.Property("UserName") + b.Property("Name") .HasColumnType("longtext"); b.HasKey("Id"); - b.ToTable("UserRoles"); + b.ToTable("Users"); }); #pragma warning restore 612, 618 } diff --git a/WorkFlowCore/UserOrganization/Organization.Framework/Organization.Framework.csproj b/WorkFlowCore/UserOrganization/Organization.Framework/Organization.Framework.csproj index a0870d829639cd728905e1b76fefa9ca9d017df5..1fdd0b302e535c215f1f573dddcde8f52915f6ea 100644 --- a/WorkFlowCore/UserOrganization/Organization.Framework/Organization.Framework.csproj +++ b/WorkFlowCore/UserOrganization/Organization.Framework/Organization.Framework.csproj @@ -17,6 +17,7 @@ + diff --git a/WorkFlowCore/UserOrganization/Organization.Framework/OrganizationDbContext.cs b/WorkFlowCore/UserOrganization/Organization.Framework/OrganizationDbContext.cs index 860ed8e9343df82520de9147068bdd23dbc643cc..5922dae7e4c1d71d45cf2e51cc3811d9640a71e1 100644 --- a/WorkFlowCore/UserOrganization/Organization.Framework/OrganizationDbContext.cs +++ b/WorkFlowCore/UserOrganization/Organization.Framework/OrganizationDbContext.cs @@ -1,4 +1,5 @@ -using JetBrains.Annotations; +using Common.EventBus.Repository4EF; +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using Organization.Core.Organizations; using Organization.Core.Roles; @@ -11,7 +12,7 @@ using System.Threading.Tasks; namespace Organization.Framework { - public class OrganizationDbContext : DbContext + public class OrganizationDbContext : DbContext, IEventBusDbContext { public OrganizationDbContext([NotNull] DbContextOptions options) : base(options) { @@ -21,5 +22,6 @@ namespace Organization.Framework public DbSet UserOrganization { get; set; } public DbSet Organizations { get; set; } public DbSet Roles { get; set; } + public DbSet CommonEventDatas { get; set; } } } diff --git a/WorkFlowCore/UserOrganization/Organization.Framework/OrganizationFrameworkModule.cs b/WorkFlowCore/UserOrganization/Organization.Framework/OrganizationFrameworkModule.cs index fe117a01896066b12975fb92347cb0efb28fa908..1927c29a1324e88b7e2a7aeef91573deda238b2b 100644 --- a/WorkFlowCore/UserOrganization/Organization.Framework/OrganizationFrameworkModule.cs +++ b/WorkFlowCore/UserOrganization/Organization.Framework/OrganizationFrameworkModule.cs @@ -1,5 +1,6 @@ using Common.Authorization; using Common.BaseRepositories4EF; +using Common.EventBus.Repository4EF; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Organization.Core.Organizations.IRepositories; @@ -29,7 +30,8 @@ namespace Organization.Framework }); services.AddScoped(); - + //注册事件仓储 + services.AddEventBusRepository4EF(); } public class OrganizationFrameworkModuleConfiguration diff --git a/WorkFlowCore/UserOrganization/Organization.Host/Startup.cs b/WorkFlowCore/UserOrganization/Organization.Host/Startup.cs index bafdc022beafa881533558e3774c6b4ca524bdd0..b8ff68c6e10d31b80e2aef1833c110b97f01dac6 100644 --- a/WorkFlowCore/UserOrganization/Organization.Host/Startup.cs +++ b/WorkFlowCore/UserOrganization/Organization.Host/Startup.cs @@ -7,6 +7,7 @@ using Common.EventBus.Kafka; using Common.MicroService; using Common.MicroService.Registers; using Common.UnitOfWork; +using Common.WebApi; using Common.WebApi.Filters; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -55,9 +56,9 @@ namespace Organization.Host }); services.AddOrganizationApp(options => { - options.AddDynamicControllers(); options.KafkaBootstrapServers = Configuration.GetValueFromManyChanels("Kafka:BootstrapServers"); }); + services.AddDynamicControllers(typeof(OrganizationAppModule).Assembly); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Organization.Host", Version = "v1" }); @@ -104,6 +105,7 @@ namespace Organization.Host app.UseAuthorization(); app.UseEventBus(); app.RunKafkaEventBus(); + app.UseWebApiExceptionHandler(); app.UseUnitOfWork(); app.UseEndpoints(endpoints => { diff --git a/WorkFlowCore/UserOrganization/Organization.IAppService/Organization.IAppService.csproj b/WorkFlowCore/UserOrganization/Organization.IAppService/Organization.IAppService.csproj index 10b6d1fd5c2d4c52111870a469ada57d456b74b8..e3764e76f76eb8f98f68c4748fe28c6a4c1ff1f4 100644 --- a/WorkFlowCore/UserOrganization/Organization.IAppService/Organization.IAppService.csproj +++ b/WorkFlowCore/UserOrganization/Organization.IAppService/Organization.IAppService.csproj @@ -7,6 +7,7 @@ + diff --git a/WorkFlowCore/UserOrganization/Organization.IAppService/OrganizationAppContractsModule.cs b/WorkFlowCore/UserOrganization/Organization.IAppService/OrganizationAppContractsModule.cs new file mode 100644 index 0000000000000000000000000000000000000000..f7aeb198c4486c23744e86fe24540ec06175967f --- /dev/null +++ b/WorkFlowCore/UserOrganization/Organization.IAppService/OrganizationAppContractsModule.cs @@ -0,0 +1,24 @@ +using Common.BackgroundWorker; +using Common.DependencyInjection; +using Common.EventBus; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using Common.Mapster; + +namespace Organization.IAppService +{ + public static class OrganizationAppContractsModule + { + public static IServiceCollection AddOrganizationAppContracts(this IServiceCollection services) + { + services.AddMapster(Assembly.GetExecutingAssembly()); + return services; + } + } +} diff --git a/WorkFlowCore/WorkFlowCore.sln b/WorkFlowCore/WorkFlowCore.sln index e3258363f68e5384c4e42799f17e2058b7bab8b9..9ae9ba69f5e09f0933d6283b3ab348b5f3a29f95 100644 --- a/WorkFlowCore/WorkFlowCore.sln +++ b/WorkFlowCore/WorkFlowCore.sln @@ -75,9 +75,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.EventBus.Kafka", "Co EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Configuration.Extension", "Commons\Common.Configuration.Extension\Common.Configuration.Extension.csproj", "{C2CAEC38-37A1-454A-B1B4-2113387210EF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.UnitOfWork", "Commons\Common.UnitOfWork\Common.UnitOfWork.csproj", "{32DC90C3-31B4-444B-80DA-63001B7BB3EE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.UnitOfWork", "Commons\Common.UnitOfWork\Common.UnitOfWork.csproj", "{32DC90C3-31B4-444B-80DA-63001B7BB3EE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.UnitOfWork4EntityFramework", "Commons\Common.UnitOfWork4EntityFramework\Common.UnitOfWork4EntityFramework.csproj", "{E1E16CA1-38EC-4F0D-AB15-F097174EC3B4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.UnitOfWork4EntityFramework", "Commons\Common.UnitOfWork4EntityFramework\Common.UnitOfWork4EntityFramework.csproj", "{E1E16CA1-38EC-4F0D-AB15-F097174EC3B4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Mapster", "Commons\Common.Mapster\Common.Mapster.csproj", "{3C37AF32-C83D-4C54-8F17-74DD0584BC50}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.SimplePluginLoader", "Commons\Common.SimplePluginLoader\Common.SimplePluginLoader.csproj", "{038F8892-EDB7-4091-AC59-D21DC44033E0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.EventBus.Repository4EF", "Commons\Common.EventBus.Repository4EF\Common.EventBus.Repository4EF.csproj", "{519E4805-268B-409C-9167-45A5DF4B8F69}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -217,6 +223,18 @@ Global {E1E16CA1-38EC-4F0D-AB15-F097174EC3B4}.Debug|Any CPU.Build.0 = Debug|Any CPU {E1E16CA1-38EC-4F0D-AB15-F097174EC3B4}.Release|Any CPU.ActiveCfg = Release|Any CPU {E1E16CA1-38EC-4F0D-AB15-F097174EC3B4}.Release|Any CPU.Build.0 = Release|Any CPU + {3C37AF32-C83D-4C54-8F17-74DD0584BC50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3C37AF32-C83D-4C54-8F17-74DD0584BC50}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3C37AF32-C83D-4C54-8F17-74DD0584BC50}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3C37AF32-C83D-4C54-8F17-74DD0584BC50}.Release|Any CPU.Build.0 = Release|Any CPU + {038F8892-EDB7-4091-AC59-D21DC44033E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {038F8892-EDB7-4091-AC59-D21DC44033E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {038F8892-EDB7-4091-AC59-D21DC44033E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {038F8892-EDB7-4091-AC59-D21DC44033E0}.Release|Any CPU.Build.0 = Release|Any CPU + {519E4805-268B-409C-9167-45A5DF4B8F69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {519E4805-268B-409C-9167-45A5DF4B8F69}.Debug|Any CPU.Build.0 = Debug|Any CPU + {519E4805-268B-409C-9167-45A5DF4B8F69}.Release|Any CPU.ActiveCfg = Release|Any CPU + {519E4805-268B-409C-9167-45A5DF4B8F69}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -255,6 +273,9 @@ Global {C2CAEC38-37A1-454A-B1B4-2113387210EF} = {3EF58BFB-DEAB-4607-9C83-3D0B0BF0CFFA} {32DC90C3-31B4-444B-80DA-63001B7BB3EE} = {3EF58BFB-DEAB-4607-9C83-3D0B0BF0CFFA} {E1E16CA1-38EC-4F0D-AB15-F097174EC3B4} = {3EF58BFB-DEAB-4607-9C83-3D0B0BF0CFFA} + {3C37AF32-C83D-4C54-8F17-74DD0584BC50} = {3EF58BFB-DEAB-4607-9C83-3D0B0BF0CFFA} + {038F8892-EDB7-4091-AC59-D21DC44033E0} = {3EF58BFB-DEAB-4607-9C83-3D0B0BF0CFFA} + {519E4805-268B-409C-9167-45A5DF4B8F69} = {3EF58BFB-DEAB-4607-9C83-3D0B0BF0CFFA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2B47C6B7-D14F-4E7A-AC89-493A7F10350B} diff --git a/WorkFlowCore/Workflow/WorkFlowCore.AppService/WorkFlowCoreAppModule.cs b/WorkFlowCore/Workflow/WorkFlowCore.AppService/WorkFlowCoreAppModule.cs index 5333e7b95531fc567b849f08042b33c07a7c59b7..f22afca8d1260dbbd1901e997863c673e42c4953 100644 --- a/WorkFlowCore/Workflow/WorkFlowCore.AppService/WorkFlowCoreAppModule.cs +++ b/WorkFlowCore/Workflow/WorkFlowCore.AppService/WorkFlowCoreAppModule.cs @@ -3,11 +3,13 @@ using Common.DynamicApi; using Common.EventBus; using Common.EventBus.Default; using Common.EventBus.Kafka; +using Common.Mapster; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Reflection; using System.Text; +using WorkFlowCore.IAppService; namespace WorkFlowCore.AppService { @@ -19,11 +21,12 @@ namespace WorkFlowCore.AppService var serviceConfig = new WorkFlowCoreAppModuleConfiguration(services); options?.Invoke(serviceConfig); - + services.AddMapster(Assembly.GetExecutingAssembly()); services.AddDependencyServices(Assembly.GetExecutingAssembly()); + services.AddWorkFlowCoreAppContracts(); + - services.AddDefautEventBus(Assembly.GetExecutingAssembly(), typeof(WorkFlowCoreModule).Assembly); services.AddKafkaEventBus(config => @@ -44,10 +47,6 @@ namespace WorkFlowCore.AppService this.services = services; } - public void AddDynamicControllers() - { - services.AddDynamicControllers(Assembly.GetExecutingAssembly()); - } /// /// kafka连接地址配置 /// diff --git a/WorkFlowCore/Workflow/WorkFlowCore.Framework/Migrations/20221022031252_addeventdata.Designer.cs b/WorkFlowCore/Workflow/WorkFlowCore.Framework/Migrations/20221022031252_addeventdata.Designer.cs new file mode 100644 index 0000000000000000000000000000000000000000..7766bdf3630a4d51edec3f65cc9af963538b033e --- /dev/null +++ b/WorkFlowCore/Workflow/WorkFlowCore.Framework/Migrations/20221022031252_addeventdata.Designer.cs @@ -0,0 +1,339 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using WorkFlowCore.Framework.Repositories4EF; + +namespace WorkFlowCore.Framework.Migrations +{ + [DbContext(typeof(WorkflowDbContext))] + [Migration("20221022031252_addeventdata")] + partial class addeventdata + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 64) + .HasAnnotation("ProductVersion", "5.0.13"); + + modelBuilder.Entity("Common.EventBus.Repository4EF.EventData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("EventContent") + .HasColumnType("longtext"); + + b.Property("IsRePublish") + .HasColumnType("bit(1)"); + + b.Property("PublishId") + .HasColumnType("char(36)"); + + b.Property("PublishTime") + .HasColumnType("datetime(6)"); + + b.Property("Publisher") + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("CommonEventDatas"); + }); + + modelBuilder.Entity("WorkFlowCore.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Workflow_User"); + }); + + modelBuilder.Entity("WorkFlowCore.WorkTasks.WorkStepInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Comment") + .HasColumnType("longtext"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("FormData") + .HasColumnType("longtext"); + + b.Property("FromForwardStepId") + .HasColumnType("char(36)"); + + b.Property("FromNodeId") + .HasColumnType("char(36)"); + + b.Property("FromNodeName") + .HasColumnType("longtext"); + + b.Property("GroupId") + .HasColumnType("longtext"); + + b.Property("HandleType") + .HasColumnType("int"); + + b.Property("HandleUser_Id") + .HasColumnType("longtext"); + + b.Property("HandleUser_Name") + .HasColumnType("longtext"); + + b.Property("HandlerTime") + .HasColumnType("datetime(6)"); + + b.Property("IsHandled") + .HasColumnType("bit(1)"); + + b.Property("IsRead") + .HasColumnType("bit(1)"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("NodeId") + .HasColumnType("char(36)"); + + b.Property("NodeName") + .HasColumnType("longtext"); + + b.Property("PreStepGroupId") + .HasColumnType("longtext"); + + b.Property("ReadTime") + .HasColumnType("datetime(6)"); + + b.Property("ResourceIds") + .HasColumnType("longtext"); + + b.Property("WorkStepType") + .HasColumnType("int"); + + b.Property("WorkTaskId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("WorkStepInfos"); + }); + + modelBuilder.Entity("WorkFlowCore.WorkTasks.WorkTaskInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("EntityFullName") + .HasColumnType("longtext"); + + b.Property("EntityKeyValue") + .HasColumnType("longtext"); + + b.Property("FormData") + .HasColumnType("longtext"); + + b.Property("IsSimulation") + .HasColumnType("bit(1)"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("WorkTaskStatus") + .HasColumnType("int"); + + b.Property("WorkflowId_Id") + .HasColumnType("char(36)"); + + b.Property("WorkflowId_VersionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("WorkTaskInfos"); + }); + + modelBuilder.Entity("WorkFlowCore.Workflows.Workflow", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ActiveVersion") + .HasColumnType("int"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("varchar(500)"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("WorkflowNo") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Workflows"); + }); + + modelBuilder.Entity("WorkFlowCore.Workflows.WorkflowVersionInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllNodes") + .HasColumnType("longtext"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("bit(1)"); + + b.Property("DeletedTime") + .HasColumnType("datetime(6)"); + + b.Property("DeletedUserId") + .HasColumnType("longtext"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("varchar(2000)"); + + b.Property("DrawingInfo") + .HasColumnType("longtext"); + + b.Property("ModifiedTime") + .HasColumnType("datetime(6)"); + + b.Property("ModifiedUserId") + .HasColumnType("longtext"); + + b.Property("NodeMaps") + .HasColumnType("longtext"); + + b.Property("VersionNo") + .HasColumnType("int"); + + b.Property("WorkflowId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("WorkflowVersionInfos"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/WorkFlowCore/Workflow/WorkFlowCore.Framework/Migrations/20221022031252_addeventdata.cs b/WorkFlowCore/Workflow/WorkFlowCore.Framework/Migrations/20221022031252_addeventdata.cs new file mode 100644 index 0000000000000000000000000000000000000000..0619edf7b4c3f3c5b61f9e56f404e8984061a8b1 --- /dev/null +++ b/WorkFlowCore/Workflow/WorkFlowCore.Framework/Migrations/20221022031252_addeventdata.cs @@ -0,0 +1,43 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace WorkFlowCore.Framework.Migrations +{ + public partial class addeventdata : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "CommonEventDatas", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CreatedUserId = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + CreationTime = table.Column(type: "datetime(6)", nullable: false), + TenantId = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Publisher = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + PublishId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + PublishTime = table.Column(type: "datetime(6)", nullable: false), + IsRePublish = table.Column(type: "bit(1)", nullable: false), + EventContent = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_CommonEventDatas", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CommonEventDatas"); + } + } +} diff --git a/WorkFlowCore/Workflow/WorkFlowCore.Framework/Migrations/WorkflowDbContextModelSnapshot.cs b/WorkFlowCore/Workflow/WorkFlowCore.Framework/Migrations/WorkflowDbContextModelSnapshot.cs index b054c00b2fe0f2237497d0c0b409918dd2ee697e..42e854369cb88e17f6eef48ae7be0b171c61da92 100644 --- a/WorkFlowCore/Workflow/WorkFlowCore.Framework/Migrations/WorkflowDbContextModelSnapshot.cs +++ b/WorkFlowCore/Workflow/WorkFlowCore.Framework/Migrations/WorkflowDbContextModelSnapshot.cs @@ -17,6 +17,41 @@ namespace WorkFlowCore.Framework.Migrations .HasAnnotation("Relational:MaxIdentifierLength", 64) .HasAnnotation("ProductVersion", "5.0.13"); + modelBuilder.Entity("Common.EventBus.Repository4EF.EventData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreatedUserId") + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("EventContent") + .HasColumnType("longtext"); + + b.Property("IsRePublish") + .HasColumnType("bit(1)"); + + b.Property("PublishId") + .HasColumnType("char(36)"); + + b.Property("PublishTime") + .HasColumnType("datetime(6)"); + + b.Property("Publisher") + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("CommonEventDatas"); + }); + modelBuilder.Entity("WorkFlowCore.Users.User", b => { b.Property("Id") diff --git a/WorkFlowCore/Workflow/WorkFlowCore.Framework/Repositories/UnitOfWork.cs b/WorkFlowCore/Workflow/WorkFlowCore.Framework/Repositories/UnitOfWork.cs index 1091eda7b291f8c27816bef14dffa97eafb13ebd..64c41e896762faa05d83e56fc55475854cafe79a 100644 --- a/WorkFlowCore/Workflow/WorkFlowCore.Framework/Repositories/UnitOfWork.cs +++ b/WorkFlowCore/Workflow/WorkFlowCore.Framework/Repositories/UnitOfWork.cs @@ -50,17 +50,7 @@ namespace WorkFlowCore.Framework.Repositories } catch (Exception) { - //回滚 - foreach (var item in removeList) - { - if(!VirtualDB.IsContains(item.GetType(), item)) - VirtualDB.Add(item.GetType(), item); - } - foreach (var item in addList) - { - if (VirtualDB.IsContains(item.GetType(), item)) - VirtualDB.Remove(item.GetType(), item); - } + Rollback(); return false; } } @@ -130,5 +120,20 @@ namespace WorkFlowCore.Framework.Repositories if (this.isActive) return; isActive = true; } + + public void Rollback() + { + //回滚 + foreach (var item in removeList) + { + if (!VirtualDB.IsContains(item.GetType(), item)) + VirtualDB.Add(item.GetType(), item); + } + foreach (var item in addList) + { + if (VirtualDB.IsContains(item.GetType(), item)) + VirtualDB.Remove(item.GetType(), item); + } + } } } diff --git a/WorkFlowCore/Workflow/WorkFlowCore.Framework/Repositories4EF/WorkflowDbContext.cs b/WorkFlowCore/Workflow/WorkFlowCore.Framework/Repositories4EF/WorkflowDbContext.cs index d2f62a90d59699d4d7fe8f9e7db6d44843048fcb..63295240fb058f10f9e781ddda076da8fb2ef859 100644 --- a/WorkFlowCore/Workflow/WorkFlowCore.Framework/Repositories4EF/WorkflowDbContext.cs +++ b/WorkFlowCore/Workflow/WorkFlowCore.Framework/Repositories4EF/WorkflowDbContext.cs @@ -1,4 +1,5 @@ -using JetBrains.Annotations; +using Common.EventBus.Repository4EF; +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; @@ -9,7 +10,7 @@ using WorkFlowCore.WorkTasks; namespace WorkFlowCore.Framework.Repositories4EF { - public class WorkflowDbContext : DbContext + public class WorkflowDbContext : DbContext, IEventBusDbContext { public WorkflowDbContext([NotNull] DbContextOptions options) : base(options) { @@ -22,7 +23,7 @@ namespace WorkFlowCore.Framework.Repositories4EF #region 组织用户 public DbSet Users { get; set; } - + public DbSet CommonEventDatas { get; set; } #endregion protected override void OnModelCreating(ModelBuilder modelBuilder) diff --git a/WorkFlowCore/Workflow/WorkFlowCore.Framework/WorkFlowCore.Framework.csproj b/WorkFlowCore/Workflow/WorkFlowCore.Framework/WorkFlowCore.Framework.csproj index 3cc14470247a764d7bfd782668e90280550d84ca..1ff4ffa666a99165925683f99256c1db753a5471 100644 --- a/WorkFlowCore/Workflow/WorkFlowCore.Framework/WorkFlowCore.Framework.csproj +++ b/WorkFlowCore/Workflow/WorkFlowCore.Framework/WorkFlowCore.Framework.csproj @@ -28,7 +28,9 @@ + + diff --git a/WorkFlowCore/Workflow/WorkFlowCore.Framework/WorkFlowCoreFrameworkModule.cs b/WorkFlowCore/Workflow/WorkFlowCore.Framework/WorkFlowCoreFrameworkModule.cs index 02814fa147762c1d8df3b7b137fac770ed3eff08..837f3779c035ce3578645accfa8c5dac259f7247 100644 --- a/WorkFlowCore/Workflow/WorkFlowCore.Framework/WorkFlowCoreFrameworkModule.cs +++ b/WorkFlowCore/Workflow/WorkFlowCore.Framework/WorkFlowCoreFrameworkModule.cs @@ -19,6 +19,10 @@ using WorkFlowCore.IRepositories; using WorkFlowCore.UserSelectors; using WorkFlowCore.Workflows; using WorkFlowCore.WorkTasks; +using Common.SimplePluginLoader; +using System.IO; +using System.Linq; +using Common.EventBus.Repository4EF; namespace WorkFlowCore.Framework { @@ -64,14 +68,27 @@ namespace WorkFlowCore.Framework }); services.AddScoped(); } + //注册事件仓储 + services.AddEventBusRepository4EF(); - var assembly = typeof(WorkFlowCoreFrameworkModule).Assembly; //注册条件和选择器 + #region 注册条件和选择器 UserSelectorManager.RegisterSelector(assembly); + services.LoadPlugins(Path.Combine(AppContext.BaseDirectory, "Plugins", "Selectors"), plugins => + { + UserSelectorManager.RegisterSelector(plugins.Select(p => p.Assembly).ToArray()); + }); ConditionManager.Registercondition(assembly); + + services.LoadPlugins(Path.Combine(AppContext.BaseDirectory, "Plugins", "Conditions"), plugins => + { + ConditionManager.Registercondition(plugins.Select(p => p.Assembly).ToArray()); + }); + #endregion + services.AddScoped(); services.AddScoped(); services.AddScoped(); @@ -82,6 +99,7 @@ namespace WorkFlowCore.Framework services.AddScoped(); services.AddScoped(); services.AddSingleton(); + } } } diff --git a/WorkFlowCore/Workflow/WorkFlowCore.Host/Startup.cs b/WorkFlowCore/Workflow/WorkFlowCore.Host/Startup.cs index cc83271dc6a1cc06eda202bac89b19ee43dc78b1..5e0a624e07ca0482aca01afa642ba714aa390a6e 100644 --- a/WorkFlowCore/Workflow/WorkFlowCore.Host/Startup.cs +++ b/WorkFlowCore/Workflow/WorkFlowCore.Host/Startup.cs @@ -5,6 +5,7 @@ using Common.EventBus.Kafka; using Common.MicroService; using Common.MicroService.Registers; using Common.UnitOfWork; +using Common.WebApi; using Common.WebApi.Filters; using Consul; using Microsoft.AspNetCore.Builder; @@ -41,11 +42,10 @@ namespace WorkFlowCore.Host { services.AddWorkFlowCoreApp(options => { - options.AddDynamicControllers(); options.KafkaBootstrapServers = Configuration.GetValueFromManyChanels("Kafka:BootstrapServers"); }); - + services.AddDynamicControllers(typeof(WorkFlowCoreModule).Assembly); services.AddWorkFlowCore(options => { options.MicroServiceGateway = Configuration.GetValueFromManyChanels("Gateway"); @@ -115,6 +115,7 @@ namespace WorkFlowCore.Host }); app.UseEventBus(); app.RunKafkaEventBus(); + app.UseWebApiExceptionHandler(); app.UseUnitOfWork(); app.UseEndpoints(endpoints => { diff --git a/WorkFlowCore/Workflow/WorkFlowCore.IAppService/WorkFlowCore.IAppService.csproj b/WorkFlowCore/Workflow/WorkFlowCore.IAppService/WorkFlowCore.IAppService.csproj index a7e8d708f1e207e54dbb47a5005e5c3389709871..42b0b969cb88916be3ddf168bc5e52b044d8d3ab 100644 --- a/WorkFlowCore/Workflow/WorkFlowCore.IAppService/WorkFlowCore.IAppService.csproj +++ b/WorkFlowCore/Workflow/WorkFlowCore.IAppService/WorkFlowCore.IAppService.csproj @@ -6,6 +6,7 @@ + diff --git a/WorkFlowCore/Workflow/WorkFlowCore.IAppService/WorkFlowCoreAppContractsModule.cs b/WorkFlowCore/Workflow/WorkFlowCore.IAppService/WorkFlowCoreAppContractsModule.cs new file mode 100644 index 0000000000000000000000000000000000000000..d875b395af9c07a7c33ad90ae8a026a95d5df483 --- /dev/null +++ b/WorkFlowCore/Workflow/WorkFlowCore.IAppService/WorkFlowCoreAppContractsModule.cs @@ -0,0 +1,24 @@ +using Common.BackgroundWorker; +using Common.DependencyInjection; +using Common.EventBus; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using Common.Mapster; + +namespace WorkFlowCore.IAppService +{ + public static class WorkFlowCoreAppContractsModule + { + public static IServiceCollection AddWorkFlowCoreAppContracts(this IServiceCollection services) + { + services.AddMapster(Assembly.GetExecutingAssembly()); + return services; + } + } +} diff --git a/WorkFlowCore/Workflow/WorkFlowCore/WorkTasks/WorkTaskManager.cs b/WorkFlowCore/Workflow/WorkFlowCore/WorkTasks/WorkTaskManager.cs index e43388fdab0db58f5eb5015c475e15c4686b44d8..cce2bffae99afbf75e99c2616ebc8d0a9ab58686 100644 --- a/WorkFlowCore/Workflow/WorkFlowCore/WorkTasks/WorkTaskManager.cs +++ b/WorkFlowCore/Workflow/WorkFlowCore/WorkTasks/WorkTaskManager.cs @@ -26,7 +26,6 @@ namespace WorkFlowCore.WorkTasks private readonly ConditionManager conditionManager; private readonly UserSelectorManager userSelectorManager; private readonly DomainEventBusService eventManager; - private readonly IUnitOfWorkManager unitOfWorkManager; private readonly WorkflowInterface workflowInterface; private readonly ILogger logger; @@ -37,9 +36,8 @@ namespace WorkFlowCore.WorkTasks , ConditionManager conditionManager , UserSelectorManager userSelectorManager , DomainEventBusService eventManager - , IUnitOfWorkManager unitOfWorkManager - ,WorkflowInterface workflowInterface - ,ILogger logger) + , WorkflowInterface workflowInterface + , ILogger logger) { this.workflowRepository = workflowRepository; this.versionRepository = versionRepository; @@ -48,7 +46,6 @@ namespace WorkFlowCore.WorkTasks this.conditionManager = conditionManager; this.userSelectorManager = userSelectorManager; this.eventManager = eventManager; - this.unitOfWorkManager = unitOfWorkManager; this.workflowInterface = workflowInterface; this.logger = logger; } @@ -75,11 +72,7 @@ namespace WorkFlowCore.WorkTasks { var worktask = new WorkTask(Guid.NewGuid(), workflowId, name, formData, entityFullName, entityKeyValue, createdUserId); worktaskInfo = worktask.ToWorkTaskInfo(); - using (var unitOfWork = unitOfWorkManager.Begin()) - { - await workTaskRepository.InsertAsync(worktaskInfo); - unitOfWork.Commit(); - } + await workTaskRepository.InsertAsync(worktaskInfo); } return worktaskInfo.ToWorkTask(); } @@ -98,11 +91,7 @@ namespace WorkFlowCore.WorkTasks var worktask = new WorkTask(Guid.NewGuid(), workflowId, name, formData, entityFullName, entityKeyValue, createdUserId); worktask.AsSimulation(); - using (var unitOfWork = unitOfWorkManager.Begin()) - { - await workTaskRepository.InsertAsync(worktask.ToWorkTaskInfo()); - unitOfWork.Commit(); - } + await workTaskRepository.InsertAsync(worktask.ToWorkTaskInfo()); return worktask; } @@ -232,11 +221,7 @@ namespace WorkFlowCore.WorkTasks stepInfos.Add(step.ToWorkStepInfo(stepInfo)); } } - using (var unitOfWork = unitOfWorkManager.Begin()) - { - await workStepRepository.UpdateManyAsync(stepInfos); - unitOfWork.Commit(); - } + await workStepRepository.UpdateManyAsync(stepInfos); } /// /// 更新同节点其它用户步骤状态为未处理 @@ -259,11 +244,7 @@ namespace WorkFlowCore.WorkTasks stepInfos.Add(step.ToWorkStepInfo(stepInfo)); } } - using (var unitOfWork = unitOfWorkManager.Begin()) - { - await workStepRepository.UpdateManyAsync(stepInfos); - unitOfWork.Commit(); - } + await workStepRepository.UpdateManyAsync(stepInfos); } @@ -286,12 +267,8 @@ namespace WorkFlowCore.WorkTasks if (startNode == null) throw new Exception("找不到可用的起始结点!"); var steps = GetApproveSteps(Guid.Empty, "", workTask, startNode, string.Empty, Guid.NewGuid().ToString()); - using (var unitOfWork = unitOfWorkManager.Begin()) - { - await workTaskRepository.UpdateAsync(workTask.ToWorkTaskInfo(workTaskInfo)); - await SendTasks(workTask, steps, workTask.FormData); - unitOfWork.Commit(); - } + await workTaskRepository.UpdateAsync(workTask.ToWorkTaskInfo(workTaskInfo)); + await SendTasks(workTask, steps, workTask.FormData); //自动处理开始节点 @@ -319,7 +296,7 @@ namespace WorkFlowCore.WorkTasks /// /// /// - private async Task HasAllHandlersWorkflowed(Guid currentWorkStepId,string currentGroupId) + private async Task HasAllHandlersWorkflowed(Guid currentWorkStepId, string currentGroupId) { var GetCountAsync = await workStepRepository.GetCountAsync(ws => ws.GroupId == currentGroupId && ws.Id != currentWorkStepId && !ws.IsHandled); return GetCountAsync == 0; @@ -355,76 +332,71 @@ namespace WorkFlowCore.WorkTasks var nextNodes = await GetNextNodes(currentNode, workTask, currentWorkStep); //更新当前处理节点为已处理 - using (var unitOfWork = unitOfWorkManager.Begin()) - { - currentWorkStep.Handle(WorkStepHandleType.Pass, comment, resourceIds); - await workStepRepository.UpdateAsync(currentWorkStep.ToWorkStepInfo(currentWorkStepInfo)); - + currentWorkStep.Handle(WorkStepHandleType.Pass, comment, resourceIds); + await workStepRepository.UpdateAsync(currentWorkStep.ToWorkStepInfo(currentWorkStepInfo)); - if (currentNode.IsWaitingAllUser) + if (currentNode.IsWaitingAllUser) + { + lock ("WorkNodeType.Sign") { - lock ("WorkNodeType.Sign") + if (!HasAllHandlersWorkflowed(currentWorkStep.Id, currentWorkStep.GroupId).Result) { - if (!HasAllHandlersWorkflowed(currentWorkStep.Id, currentWorkStep.GroupId).Result) - { - return ProveResult.Succeed(steps); - } + return ProveResult.Succeed(steps); } } - else - { - await UpdateOtherStepsStatusWithUnWorkOfNode(currentWorkStep); - } - //如果是会签操作,则确保所有会签中的操作都完成了才进行下一步 - if (nextNodes.Count == 1 && nextNodes[0].NodeType == WorkNodeType.Sign) + } + else + { + await UpdateOtherStepsStatusWithUnWorkOfNode(currentWorkStep); + } + //如果是会签操作,则确保所有会签中的操作都完成了才进行下一步 + if (nextNodes.Count == 1 && nextNodes[0].NodeType == WorkNodeType.Sign) + { + //会签 + //等待所有待处理的处理才继续 + lock ("WorkNodeType.Sign") { - //会签 - //等待所有待处理的处理才继续 - lock ("WorkNodeType.Sign") + if (HasOnHandingSignSteps(currentWorkStep.NodeId, currentWorkStep.GroupId).Result) { - if (HasOnHandingSignSteps(currentWorkStep.NodeId, currentWorkStep.GroupId).Result) - { - return ProveResult.Succeed(steps); ; - } + return ProveResult.Succeed(steps); ; } } - var nextGroupId = Guid.NewGuid().ToString(); + } + var nextGroupId = Guid.NewGuid().ToString(); - foreach (var node in nextNodes) + foreach (var node in nextNodes) + { + //如果 指定了处理人,则直接派给处理人 + //如果指定了 抄送(只读)人员,直接推送给抄送人员 + if (userSelectors != null && userSelectors.Any()) { - //如果 指定了处理人,则直接派给处理人 - //如果指定了 抄送(只读)人员,直接推送给抄送人员 - if (userSelectors != null && userSelectors.Any()) + GetUsersByUserSelectors(userSelectors, null, (selector, user) => { - GetUsersByUserSelectors(userSelectors, null, (selector, user) => + steps.Add(new WorkStep(Guid.NewGuid(), workTask.Id, currentWorkStep.NodeId, currentNode.Name, node.Id, node.Name, new User { - steps.Add(new WorkStep(Guid.NewGuid(), workTask.Id, currentWorkStep.NodeId, currentNode.Name, node.Id, node.Name, new User - { - Id = user.Id, - Name = user.Name - }, selector.HandleType == NodeUser.NodeHandleType.Handle ? WorkStepType.Handle : WorkStepType.ReadOnly, currentWorkStep.GroupId, nextGroupId)); - }); - } - else - { - steps.AddRange(GetApproveSteps(currentWorkStep.NodeId, currentNode.Name, workTask, node, currentWorkStep.GroupId, nextGroupId)); - } + Id = user.Id, + Name = user.Name + }, selector.HandleType == NodeUser.NodeHandleType.Handle ? WorkStepType.Handle : WorkStepType.ReadOnly, currentWorkStep.GroupId, nextGroupId)); + }); + } + else + { + steps.AddRange(GetApproveSteps(currentWorkStep.NodeId, currentNode.Name, workTask, node, currentWorkStep.GroupId, nextGroupId)); } + } - if (steps.Count == 0 && currentNode.NodeType != WorkNodeType.End) - return ProveResult.Failed("找不到可以处理的下一个步骤!"); - await SendTasks(workTask, steps, formData); - if (!unitOfWork.Commit()) - ProveResult.Failed("提交失败"); + if (steps.Count == 0 && currentNode.NodeType != WorkNodeType.End) + return ProveResult.Failed("找不到可以处理的下一个步骤!"); + await SendTasks(workTask, steps, formData); + + //检查更新流程状态为审判中或者结束 + await CheckAndSetTaskProcessing(workTask, workTaskInfo, currentNode); + await CheckAndSetTaskProcessed(workTask, workTaskInfo, currentNode); - //检查更新流程状态为审判中或者结束 - await CheckAndSetTaskProcessing(workTask, workTaskInfo, currentNode); - await CheckAndSetTaskProcessed(workTask, workTaskInfo, currentNode); - } //自动处理结束节点 if (nextNodes.Count == 1 && nextNodes[0].NodeType == WorkNodeType.End) { @@ -475,39 +447,35 @@ namespace WorkFlowCore.WorkTasks return ProveResult.Failed("开始步骤无法拒绝!"); //更新当前处理节点为已处理 - using (var unitOfWork = unitOfWorkManager.Begin()) - { - currentWorkStep.Handle(WorkStepHandleType.Reject, comment, resourceIds); - await workStepRepository.UpdateAsync(currentWorkStep.ToWorkStepInfo(currentWorkStepInfo)); - var steps = new List(); - - var nextNodes = await GetNextNodes(currentNode, workTask, currentWorkStep); - //如果下一个节点是会签,则同组的步骤都要撤回 - if (nextNodes.Count == 1 && nextNodes[0].NodeType == WorkNodeType.Sign) - { - await UpdateOtherStepsStatusWithUnWork(currentWorkStep.NodeId, currentWorkStep.GroupId); - } - + currentWorkStep.Handle(WorkStepHandleType.Reject, comment, resourceIds); + await workStepRepository.UpdateAsync(currentWorkStep.ToWorkStepInfo(currentWorkStepInfo)); + var steps = new List(); - //获取拒绝的步骤(如果指定绝节节点则获取拒绝节点,否则退回上一步的节点,处理人员仍然 是上一步的人员) - var rejectInfo = await GetRejectInfo(currentNode, workTask, currentWorkStep); - var rejectSteps = rejectInfo.Item1; - steps.AddRange(rejectSteps); - if (steps.Count == 0) - return ProveResult.Failed("找不到可以处理的下一个步骤!"); + var nextNodes = await GetNextNodes(currentNode, workTask, currentWorkStep); + //如果下一个节点是会签,则同组的步骤都要撤回 + if (nextNodes.Count == 1 && nextNodes[0].NodeType == WorkNodeType.Sign) + { + await UpdateOtherStepsStatusWithUnWork(currentWorkStep.NodeId, currentWorkStep.GroupId); + } - //如果拒绝返回的节点是开始 节点,则更新流程状态为待审批 - var rejectNodes = rejectInfo.Item2; - var startNode = rejectNodes.FirstOrDefault(n => n.NodeType == WorkNodeType.Begin); - if (startNode != null) - { - await CheckAndTaskPendding(workTask, workTaskInfo, startNode); - } - await SendTasks(workTask, steps, formData); + //获取拒绝的步骤(如果指定绝节节点则获取拒绝节点,否则退回上一步的节点,处理人员仍然 是上一步的人员) + var rejectInfo = await GetRejectInfo(currentNode, workTask, currentWorkStep); + var rejectSteps = rejectInfo.Item1; + steps.AddRange(rejectSteps); + if (steps.Count == 0) + return ProveResult.Failed("找不到可以处理的下一个步骤!"); - return unitOfWork.Commit(ProveResult.Succeed(steps), ProveResult.Failed("提交失败")); + //如果拒绝返回的节点是开始 节点,则更新流程状态为待审批 + var rejectNodes = rejectInfo.Item2; + var startNode = rejectNodes.FirstOrDefault(n => n.NodeType == WorkNodeType.Begin); + if (startNode != null) + { + await CheckAndTaskPendding(workTask, workTaskInfo, startNode); } + + await SendTasks(workTask, steps, formData); + return ProveResult.Succeed(steps); } @@ -551,41 +519,38 @@ namespace WorkFlowCore.WorkTasks } - using (var unitOfWork = unitOfWorkManager.Begin()) + //如果已读则不处理,否则执行撤回||如果下一个节点是会签节点,则允许撤回当前的操作重新审批 + if (nextSteps.Any() && !nextSteps.Where(s => s.IsRead || s.IsHandled).Any() || nextNodes.Count == 1 && nextNodes[0].NodeType == WorkNodeType.Sign) { - //如果已读则不处理,否则执行撤回||如果下一个节点是会签节点,则允许撤回当前的操作重新审批 - if (nextSteps.Any() && !nextSteps.Where(s => s.IsRead || s.IsHandled).Any() || nextNodes.Count == 1 && nextNodes[0].NodeType == WorkNodeType.Sign) - { - //设置后续节点为未处理 - var stepInfos = new List(); - foreach (var nextStepsInfo in nextSteps) - { - var nextStep = nextStepsInfo.ToWorkStep(); - nextStep.Handle(WorkStepHandleType.UnWork, $"撤回:{comment}"); - stepInfos.Add(nextStep.ToWorkStepInfo(nextStepsInfo)); - } - await workStepRepository.UpdateManyAsync(stepInfos); - //设置当前节点为撤回状态 - //新插入当前步骤 - var withdrawStep = currentWorkStep.Copy(); - withdrawStep.Handle(WorkStepHandleType.Withdraw, comment); - await workStepRepository.InsertAsync(withdrawStep.ToWorkStepInfo()); - //新插入当前步骤 - var newStep = currentWorkStep.Copy(); - newStep.SetReaded();//对于撤回新插入的记录,它应该是已读的 - await workStepRepository.InsertAsync(newStep.ToWorkStepInfo()); - steps.Add(newStep); - } - else + //设置后续节点为未处理 + var stepInfos = new List(); + foreach (var nextStepsInfo in nextSteps) { - return ProveResult.Failed("下一步骤已读或已处理,无法撤回!"); + var nextStep = nextStepsInfo.ToWorkStep(); + nextStep.Handle(WorkStepHandleType.UnWork, $"撤回:{comment}"); + stepInfos.Add(nextStep.ToWorkStepInfo(nextStepsInfo)); } - await CheckAndTaskPendding(workTask, workTaskInfo, currentNode); - - if (steps.Count == 0) - return ProveResult.Failed("找不到可以处理的下一个步骤!"); - return unitOfWork.Commit(ProveResult.Succeed(steps), ProveResult.Failed("提交失败")); + await workStepRepository.UpdateManyAsync(stepInfos); + //设置当前节点为撤回状态 + //新插入当前步骤 + var withdrawStep = currentWorkStep.Copy(); + withdrawStep.Handle(WorkStepHandleType.Withdraw, comment); + await workStepRepository.InsertAsync(withdrawStep.ToWorkStepInfo()); + //新插入当前步骤 + var newStep = currentWorkStep.Copy(); + newStep.SetReaded();//对于撤回新插入的记录,它应该是已读的 + await workStepRepository.InsertAsync(newStep.ToWorkStepInfo()); + steps.Add(newStep); } + else + { + return ProveResult.Failed("下一步骤已读或已处理,无法撤回!"); + } + await CheckAndTaskPendding(workTask, workTaskInfo, currentNode); + + if (steps.Count == 0) + return ProveResult.Failed("找不到可以处理的下一个步骤!"); + return ProveResult.Succeed(steps); } /// /// 获取转发出去的步骤id @@ -696,39 +661,36 @@ namespace WorkFlowCore.WorkTasks //设置当前节点为转发状态 - using (var unitOfWork = unitOfWorkManager.Begin()) + currentWorkStep.Handle(WorkStepHandleType.Forward, comment); + await workStepRepository.UpdateAsync(currentWorkStep.ToWorkStepInfo(currentWorkStepInfo)); + //插入新处理人的处理步骤 + //遍历用户 选择器获取实际用户 并转发处理 + foreach (var selector in UserSelectors) { - currentWorkStep.Handle(WorkStepHandleType.Forward, comment); - await workStepRepository.UpdateAsync(currentWorkStep.ToWorkStepInfo(currentWorkStepInfo)); - //插入新处理人的处理步骤 - //遍历用户 选择器获取实际用户 并转发处理 - foreach (var selector in UserSelectors) + var userSelector = userSelectorManager.GetUserSelector(selector.SelectorId); + foreach (var section in selector.Selections) { - var userSelector = userSelectorManager.GetUserSelector(selector.SelectorId); - foreach (var section in selector.Selections) + var _users = userSelector.GetUsers(new SelectorInput { - var _users = userSelector.GetUsers(new SelectorInput - { - SelectionId = section.Id, - Expression = selector.Parameter, - WorkTask = workTask - }); - - _users.ForEach(user => - { - var newStep = currentWorkStep.Copy(); - newStep.SetHandleUser(user); - newStep.FromForward(currentWorkStep.Id); - workStepRepository.InsertAsync(newStep.ToWorkStepInfo()); - steps.Add(newStep); - }); - } + SelectionId = section.Id, + Expression = selector.Parameter, + WorkTask = workTask + }); + _users.ForEach(user => + { + var newStep = currentWorkStep.Copy(); + newStep.SetHandleUser(user); + newStep.FromForward(currentWorkStep.Id); + workStepRepository.InsertAsync(newStep.ToWorkStepInfo()); + steps.Add(newStep); + }); } - if (steps.Count == 0) - return ProveResult.Failed("找不到可以处理的下一个步骤!"); - return unitOfWork.Commit(ProveResult.Succeed(steps), ProveResult.Failed("提交失败")); + } + if (steps.Count == 0) + return ProveResult.Failed("找不到可以处理的下一个步骤!"); + return ProveResult.Succeed(steps); } /// @@ -740,7 +702,7 @@ namespace WorkFlowCore.WorkTasks private async Task HasOnHandingSignSteps(Guid currentNodeId, string stepGroupId) { var steps = await workStepRepository.GetCountAsync(ws => ws.GroupId == stepGroupId && ws.IsHandled == false && ws.NodeId != currentNodeId); - return steps>0; + return steps > 0; } /// diff --git a/WorkFlowCore/Workflow/WorkFlowCore/Workflows/WorkflowManager.cs b/WorkFlowCore/Workflow/WorkFlowCore/Workflows/WorkflowManager.cs index 3525e4a3621a1cadb5cf893fee849a9e0c36d488..f33336b1b576b53eb606c78d203ead4ae1d1100d 100644 --- a/WorkFlowCore/Workflow/WorkFlowCore/Workflows/WorkflowManager.cs +++ b/WorkFlowCore/Workflow/WorkFlowCore/Workflows/WorkflowManager.cs @@ -19,19 +19,16 @@ namespace WorkFlowCore.Workflows private readonly IBasicRepository workflowRepository; private readonly IBasicRepository versionRepository; private readonly DomainEventBusService eventManager; - private readonly IUnitOfWorkManager unitOfWorkManager; private readonly WorkflowInterface workflowInterface; public WorkflowManager(IBasicRepository workflowRepository , IBasicRepository versionRepository , DomainEventBusService eventManager - , IUnitOfWorkManager unitOfWorkManager , WorkflowInterface workflowInterface) { this.workflowRepository = workflowRepository; this.versionRepository = versionRepository; this.eventManager = eventManager; - this.unitOfWorkManager = unitOfWorkManager; this.workflowInterface = workflowInterface; } @@ -68,15 +65,11 @@ namespace WorkFlowCore.Workflows public async Task CreateWorkflow(string workflowNo, string name, string description) { - using (var unitOfWork = unitOfWorkManager.Begin()) - { - var workflow = new Workflow(Guid.NewGuid(), workflowNo, name, description); - workflow = await workflowRepository.InsertAsync(workflow); - var workflowVersion = new WorkflowVersion(Guid.NewGuid(), workflow.Id, workflow.ActiveVersion, string.Empty, description); - await versionRepository.InsertAsync(workflowVersion.ToWorkflowVersionInfo()); - unitOfWork.Commit(); - return workflow; - } + var workflow = new Workflow(Guid.NewGuid(), workflowNo, name, description); + workflow = await workflowRepository.InsertAsync(workflow); + var workflowVersion = new WorkflowVersion(Guid.NewGuid(), workflow.Id, workflow.ActiveVersion, string.Empty, description); + await versionRepository.InsertAsync(workflowVersion.ToWorkflowVersionInfo()); + return workflow; } /// /// 更新流程激活版本 @@ -85,13 +78,10 @@ namespace WorkFlowCore.Workflows /// public async Task UpdateWorkflowActiveVersion(Guid workflowId, int activeVersion) { - using (var unitOfWork = unitOfWorkManager.Begin()) - { - var workflow = await workflowRepository.GetAsync(workflowId); - workflow.UpdateActiveVersion(activeVersion); - await workflowRepository.UpdateAsync(workflow); - return unitOfWork.Commit(true, false); - } + var workflow = await workflowRepository.GetAsync(workflowId); + workflow.UpdateActiveVersion(activeVersion); + await workflowRepository.UpdateAsync(workflow); + return true; } /// /// 删除流程 @@ -103,12 +93,8 @@ namespace WorkFlowCore.Workflows var tasks = await workflowRepository.GetListAsync(wt => wt.Id == workflowid); tasks.ForEach(t => t.Deleted = true); - - using (var unitOfWork = unitOfWorkManager.Begin()) - { - await workflowRepository.UpdateManyAsync(tasks); - return unitOfWork.Commit(true, false); - } + await workflowRepository.UpdateManyAsync(tasks); + return true; } /// /// 删除流程版本 @@ -118,11 +104,8 @@ namespace WorkFlowCore.Workflows /// public async Task DeleteWorkflowVersion(Guid workflowid, int versionId) { - using (var unitOfWork = unitOfWorkManager.Begin()) - { - await versionRepository.DeleteManyAsync(wt => wt.WorkflowId == workflowid && wt.VersionNo == versionId); - return unitOfWork.Commit(true, false); - } + await versionRepository.DeleteManyAsync(wt => wt.WorkflowId == workflowid && wt.VersionNo == versionId); + return true; } private List GetNewNodeMaps(List workflowLines, List workflowNodes) @@ -184,38 +167,36 @@ namespace WorkFlowCore.Workflows { var workflow = await workflowRepository.GetAsync(workflowId); workflow.Update(name, description); - using (var unitOfWork = unitOfWorkManager.Begin()) - { - await workflowRepository.UpdateAsync(workflow); - WorkflowVersion version = null; - var versionInfo = await workflowInterface.GetWorkflowVersionInfo(workflowId, versionNo); - if (versionInfo == null) - { - //新建版本 - version = new WorkflowVersion(Guid.NewGuid(), workflowId, versionNo, drawingInfo, versionDescription); - version.SetNodeMaps(GetNewNodeMaps(workflowLines, workflowNodes)); - await versionRepository.InsertAsync(version.ToWorkflowVersionInfo()); - } - else - { - version = versionInfo.ToWorkflowVersion(); - version.SetNodeMaps(GetNewNodeMaps(workflowLines, workflowNodes)); - version.Update(versionNo, drawingInfo, versionDescription); - await versionRepository.UpdateAsync(version.ToWorkflowVersionInfo(versionInfo)); - } - //推送设计流程信息变更事件 - eventManager.Publish(new WorkflowVersionChangeEventData - { - Workflow = workflow, - WorkflowVersion = version, - }); - return unitOfWork.Commit(workflow, null); + await workflowRepository.UpdateAsync(workflow); + WorkflowVersion version = null; + var versionInfo = await workflowInterface.GetWorkflowVersionInfo(workflowId, versionNo); + if (versionInfo == null) + { + //新建版本 + version = new WorkflowVersion(Guid.NewGuid(), workflowId, versionNo, drawingInfo, versionDescription); + version.SetNodeMaps(GetNewNodeMaps(workflowLines, workflowNodes)); + await versionRepository.InsertAsync(version.ToWorkflowVersionInfo()); } + else + { + version = versionInfo.ToWorkflowVersion(); + version.SetNodeMaps(GetNewNodeMaps(workflowLines, workflowNodes)); + version.Update(versionNo, drawingInfo, versionDescription); + await versionRepository.UpdateAsync(version.ToWorkflowVersionInfo(versionInfo)); + } + //推送设计流程信息变更事件 + eventManager.Publish(new WorkflowVersionChangeEventData + { + Workflow = workflow, + WorkflowVersion = version, + }); + + return workflow; } #endregion - + } } diff --git a/admin/vue-admin-template/.env.development b/admin/vue-admin-template/.env.development index 89b492c167da3caf13fcd562197bb3ff3e35d472..a10dfae8585bb351b65bd35b8ccca134ccbe2fcd 100644 --- a/admin/vue-admin-template/.env.development +++ b/admin/vue-admin-template/.env.development @@ -2,5 +2,5 @@ ENV = 'development' # base api -VUE_APP_BASE_API = 'http://localhost:7001/' +VUE_APP_BASE_API = 'http://localhost:5400/' //VUE_APP_BASE_API = 'https://localhost:6001/api' diff --git a/admin/vue-admin-template/public/config.js b/admin/vue-admin-template/public/config.js index 279e5beaac10640aac21a81672ff2a6252a6b64f..db06349cc041da602aa5fac8aec143fb97258f09 100644 --- a/admin/vue-admin-template/public/config.js +++ b/admin/vue-admin-template/public/config.js @@ -1,3 +1,3 @@ -window.globalconfig_baseURL="baseURL" \ No newline at end of file +window.globalconfig_baseURL="" \ No newline at end of file diff --git a/localapp-workflow.bat b/localapp-workflow.bat index c2ee0d94bddedea979ff78346a16eaedd56f9637..2a785384345a0bf6590b104561deb935f86d6d2b 100644 --- a/localapp-workflow.bat +++ b/localapp-workflow.bat @@ -5,7 +5,7 @@ set ASPNETCORE_ENVIRONMENT=Development cd WorkFlowCore\Workflow\WorkFlowCore.Host dotnet build cd bin\Debug\netcoreapp3.1\ -dotnet "WorkFlowCore.Host.dll" --urls "http://[*]:5100" --ip "172.26.96.1" --port "5100" --servicename workflow --KafkaBootstrapServers "kafka1:9092" --ConnectionString "Database=Workflow;Data Source=localhost;Port=3306;UserId=root;Password=123456;Charset=utf8;TreatTinyAsBoolean=false;Allow User Variables=True" +dotnet "WorkFlowCore.Host.dll" --Gateway "http://localhost:5400/" --urls "http://[*]:5100" --ip "172.26.96.1" --port "5100" --servicename workflow --KafkaBootstrapServers "kafka1:9092" --ConnectionString "Database=Workflow;Data Source=localhost;Port=3306;UserId=root;Password=123456;Charset=utf8;TreatTinyAsBoolean=false;Allow User Variables=True"