From 0848c8b7e5ebc4d4442e0a513d60d9b40a8c4b8e Mon Sep 17 00:00:00 2001 From: nsnail Date: Fri, 8 Nov 2024 14:55:35 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E2=99=BB=EF=B8=8F=20seedDataInsert?= =?UTF-8?q?edEventAsync=20(#190)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: tk --- assets/res/NetAdmin.Statements.ln | 2 ++ .../Events/SeedDataInsertedEvent.cs | 36 +++++++++++++++++++ .../NetAdmin.Host/Filters/ApiResultHandler.cs | 9 +++-- .../NetAdmin.Host/Subscribers/SqlProfiler.cs | 15 ++++++++ .../NetAdmin.Infrastructure/Constant/Chars.cs | 2 +- .../Utils/FreeSqlBuilder.cs | 21 ++++++----- .../Extensions/ServiceCollectionExtensions.cs | 7 ++-- 7 files changed, 78 insertions(+), 14 deletions(-) create mode 100644 src/backend/NetAdmin.Domain/Events/SeedDataInsertedEvent.cs diff --git a/assets/res/NetAdmin.Statements.ln b/assets/res/NetAdmin.Statements.ln index 6aafb9b4..f50f2ded 100644 --- a/assets/res/NetAdmin.Statements.ln +++ b/assets/res/NetAdmin.Statements.ln @@ -15,6 +15,8 @@ XML注释文件不存在 时间表达式 用户名不能是手机号码 用户名长度4位以上 +种子数据插入完成 +记录已存在 请求对象不能为空 邀请码不正确 配置文件初始化完毕 diff --git a/src/backend/NetAdmin.Domain/Events/SeedDataInsertedEvent.cs b/src/backend/NetAdmin.Domain/Events/SeedDataInsertedEvent.cs new file mode 100644 index 00000000..9279fcc9 --- /dev/null +++ b/src/backend/NetAdmin.Domain/Events/SeedDataInsertedEvent.cs @@ -0,0 +1,36 @@ +namespace NetAdmin.Domain.Events; + +/// +/// 种子数据插入完毕事件 +/// +public sealed record SeedDataInsertedEvent : DataAbstraction, IEventSource +{ + /// + /// Initializes a new instance of the class. + /// + public SeedDataInsertedEvent(int insertedCount) + { + InsertedCount = insertedCount; + EventId = nameof(SeedDataInsertedEvent); + } + + /// + public CancellationToken CancellationToken { get; } + + /// + public DateTime CreatedTime { get; } + + /// + public string EventId { get; } + + /// + public bool IsConsumOnce { get; } + + /// + public object Payload { get; } + + /// + /// 插入数量 + /// + public int InsertedCount { get; set; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin.Host/Filters/ApiResultHandler.cs b/src/backend/NetAdmin.Host/Filters/ApiResultHandler.cs index cc242292..edd7d494 100644 --- a/src/backend/NetAdmin.Host/Filters/ApiResultHandler.cs +++ b/src/backend/NetAdmin.Host/Filters/ApiResultHandler.cs @@ -23,8 +23,13 @@ public abstract class ApiResultHandler /// public IActionResult OnException(ExceptionContext context, ExceptionMetadata metadata) { - var naException = context.Exception switch { NetAdminException ex => ex, _ => null }; - var errorCode = naException?.Code ?? ErrorCodes.Unhandled; + var naException = context.Exception switch { + NetAdminException ex => ex + , _ => context.Exception.Message.Contains(Chars.FLG_DB_EXCEPTION_PRIMARY_KEY_CONFLICT) + ? new NetAdminInvalidOperationException(Ln.记录已存在) + : null + }; + var errorCode = naException?.Code ?? ErrorCodes.Unhandled; var result = RestfulResult(errorCode, metadata.Data , naException is NetAdminValidateException vEx ? vEx.ValidateResults diff --git a/src/backend/NetAdmin.Host/Subscribers/SqlProfiler.cs b/src/backend/NetAdmin.Host/Subscribers/SqlProfiler.cs index 78ebe786..1dbff877 100644 --- a/src/backend/NetAdmin.Host/Subscribers/SqlProfiler.cs +++ b/src/backend/NetAdmin.Host/Subscribers/SqlProfiler.cs @@ -29,6 +29,21 @@ public sealed class SqlProfiler(ILogger logger) : IEventSubscriber return Task.CompletedTask; } + /// + /// 种子数据插入完毕 + /// + [EventSubscribe(nameof(SeedDataInsertedEvent))] + public Task SeedDataInsertedEventAsync(EventHandlerExecutingContext context) + { + var source = context.Source as SeedDataInsertedEvent; + logger.Info(source); + if (App.WebHostEnvironment.IsDevelopment()) { + Environment.Exit(0); + } + + return Task.CompletedTask; + } + /// /// 同步数据库结构之后 /// diff --git a/src/backend/NetAdmin.Infrastructure/Constant/Chars.cs b/src/backend/NetAdmin.Infrastructure/Constant/Chars.cs index 824894cb..5d660e8e 100644 --- a/src/backend/NetAdmin.Infrastructure/Constant/Chars.cs +++ b/src/backend/NetAdmin.Infrastructure/Constant/Chars.cs @@ -15,7 +15,7 @@ public static class Chars public const string FLG_CONTEXT_USER_ID = nameof(FLG_CONTEXT_USER_ID); public const string FLG_CONTEXT_USER_INFO = nameof(FLG_CONTEXT_USER_INFO); public const string FLG_CRON_PER_SECS = "* * * * * *"; - public const string FLG_DB_EXCEPTION_PRIVATE_KEY_CONFLICT = "PRIMARY KEY"; + public const string FLG_DB_EXCEPTION_PRIMARY_KEY_CONFLICT = "PRIMARY KEY"; public const string FLG_DB_FIELD_TYPE_NVARCHAR = "nvarchar"; public const string FLG_DB_FIELD_TYPE_NVARCHAR_1022 = "nvarchar(1022)"; public const string FLG_DB_FIELD_TYPE_NVARCHAR_127 = "nvarchar(127)"; diff --git a/src/backend/NetAdmin.Infrastructure/Utils/FreeSqlBuilder.cs b/src/backend/NetAdmin.Infrastructure/Utils/FreeSqlBuilder.cs index cb86ee6f..e5e58b8e 100644 --- a/src/backend/NetAdmin.Infrastructure/Utils/FreeSqlBuilder.cs +++ b/src/backend/NetAdmin.Infrastructure/Utils/FreeSqlBuilder.cs @@ -13,7 +13,7 @@ public sealed class FreeSqlBuilder(DatabaseOptions databaseOptions) /// /// 构建freeSql对象 /// - public IFreeSql Build(FreeSqlInitMethods initMethods) + public IFreeSql Build(FreeSqlInitMethods initMethods, Func onSeedDataInserted = null) { var freeSql = new FreeSql.FreeSqlBuilder() #if DBTYPE_SQLSERVER @@ -25,7 +25,7 @@ public sealed class FreeSqlBuilder(DatabaseOptions databaseOptions) .UseGenerateCommandParameterWithLambda(true) .UseAutoSyncStructure(initMethods.HasFlag(FreeSqlInitMethods.SyncStructure)) .Build(); - _ = InitDbAsync(freeSql, initMethods); // 初始化数据库 ,异步 + _ = InitDbAsync(freeSql, initMethods, onSeedDataInserted); // 初始化数据库 ,异步 return freeSql; } @@ -69,7 +69,7 @@ public sealed class FreeSqlBuilder(DatabaseOptions databaseOptions) /// /// 初始化数据库 /// - private Task InitDbAsync(IFreeSql freeSql, FreeSqlInitMethods initMethods) + private Task InitDbAsync(IFreeSql freeSql, FreeSqlInitMethods initMethods, Func onSeedDataInserted) { return Task.Run(() => { if (initMethods == FreeSqlInitMethods.None) { @@ -82,7 +82,8 @@ public sealed class FreeSqlBuilder(DatabaseOptions databaseOptions) } if (initMethods.HasFlag(FreeSqlInitMethods.InsertSeedData)) { - InsertSeedData(freeSql, entityTypes); + var insertCount = InsertSeedData(freeSql, entityTypes); + _ = onSeedDataInserted?.Invoke(insertCount); } if (initMethods.HasFlag(FreeSqlInitMethods.CompareStructure)) { @@ -94,8 +95,9 @@ public sealed class FreeSqlBuilder(DatabaseOptions databaseOptions) /// /// 插入种子数据 /// - private void InsertSeedData(IFreeSql freeSql, IEnumerable entityTypes) + private int InsertSeedData(IFreeSql freeSql, IEnumerable entityTypes) { + var ret = 0; foreach (var entityType in entityTypes) { var file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, databaseOptions.SeedDataRelativePath, $"{entityType.Name}.json"); if (!File.Exists(file)) { @@ -112,8 +114,8 @@ public sealed class FreeSqlBuilder(DatabaseOptions databaseOptions) }; _ = jsonSerializerOptions.Converters.AddDateTimeTypeConverters(); - var jsonTypeInfo = JsonTypeInfo.CreateJsonTypeInfo(typeof(IEnumerable<>).MakeGenericType(entityType), jsonSerializerOptions); - var entities = JsonSerializer.Deserialize(fs, jsonTypeInfo); + var jsonTypeInfo = JsonTypeInfo.CreateJsonTypeInfo(typeof(IEnumerable<>).MakeGenericType(entityType), jsonSerializerOptions); + dynamic entities = JsonSerializer.Deserialize(fs, jsonTypeInfo); // 如果表存在数据,跳过 var select = typeof(IFreeSql).GetMethod(nameof(freeSql.Select), 1, Type.EmptyTypes)?.MakeGenericMethod(entityType).Invoke(freeSql, null); @@ -129,8 +131,11 @@ public sealed class FreeSqlBuilder(DatabaseOptions databaseOptions) var insert = MakeInsertMethod(entityType); - _ = insert?.Invoke(rep, [entities]); + _ = insert?.Invoke(rep, [entities]); + ret += entities!.Count; } + + return ret; } /// diff --git a/src/backend/NetAdmin.SysComponent.Host/Extensions/ServiceCollectionExtensions.cs b/src/backend/NetAdmin.SysComponent.Host/Extensions/ServiceCollectionExtensions.cs index 0176da1e..1e47132f 100644 --- a/src/backend/NetAdmin.SysComponent.Host/Extensions/ServiceCollectionExtensions.cs +++ b/src/backend/NetAdmin.SysComponent.Host/Extensions/ServiceCollectionExtensions.cs @@ -32,12 +32,13 @@ public static class ServiceCollectionExtensions // #if !DEBUG // initOptions = FreeSqlInitOptions.None; // #endif - var dbOptions = App.GetOptions(); - var fSql = new FreeSqlBuilder(dbOptions).Build(initMethods); + var dbOptions = App.GetOptions(); + var eventPublisher = App.GetService(); + + var fSql = new FreeSqlBuilder(dbOptions).Build(initMethods, count => eventPublisher.PublishAsync(new SeedDataInsertedEvent(count))); _ = me.AddSingleton(fSql); fSql.Aop.AuditValue += SqlAuditor.DataAuditHandler; // Insert/Update自动值处理 - var eventPublisher = App.GetService(); #pragma warning disable VSTHRD110