From 2032b8d3d513503853a0b6cc577543cb611baa81 Mon Sep 17 00:00:00 2001 From: FunCoder Date: Thu, 10 Apr 2025 09:04:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=E5=88=9D=E5=A7=8B=E5=8C=96=E8=A1=A8?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E4=B9=8B=E5=89=8D=E5=92=8C=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E7=A7=8D=E5=AD=90=E6=95=B0=E6=8D=AE=E4=B9=8B=E5=90=8E?= =?UTF-8?q?=E7=9A=84=E5=8F=8D=E5=B0=84=E5=9B=9E=E8=B0=83=EF=BC=8C=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E7=B3=BB=E7=BB=9F=E7=89=88=E6=9C=AC=E6=AF=94=E8=BE=83?= =?UTF-8?q?=EF=BC=8C=E6=96=B9=E4=BE=BF=E7=B3=BB=E7=BB=9F=E5=86=85=E9=83=A8?= =?UTF-8?q?=E7=9A=84=E8=A1=A8=E7=BB=93=E6=9E=84=E3=80=81=E7=A7=8D=E5=AD=90?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=9A=84=E5=B9=B3=E6=BB=91=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Admin.NET/Admin.NET.Application/Startup.cs | 48 +++++++++++ Admin.NET/Admin.NET.Core/Const/ConfigConst.cs | 9 +++ .../SeedData/SysConfigSeedData.cs | 2 + .../Admin.NET.Core/SqlSugar/SqlSugarSetup.cs | 80 +++++++++++++++++++ Admin.NET/Admin.NET.Core/Utils/CommonUtil.cs | 42 ++++++++++ 5 files changed, 181 insertions(+) diff --git a/Admin.NET/Admin.NET.Application/Startup.cs b/Admin.NET/Admin.NET.Application/Startup.cs index 29aa3182..ae7fda8d 100644 --- a/Admin.NET/Admin.NET.Application/Startup.cs +++ b/Admin.NET/Admin.NET.Application/Startup.cs @@ -19,4 +19,52 @@ public class Startup : AppStartup public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { } + /// + /// 初始化与升级数据,在初始化表结构之前调用 + /// + /// + /// 旧版本,0表示从来没有设置过,-1表示当前连接不是主数据库,从SysConfig表获取的 + /// 当前版本,由ConfigConst.SysCurrentVersion转换的整数版本 + public void BeforeInitTable(SqlSugarScopeProvider dbProvider, long oldVerion, long currentVersion) + { + //比较版本号对数据库进行升级结构、种子数据等 + } + /// + /// 初始化与升级数据,在初始化种子数据之后调用 + /// + /// + /// 旧版本,0表示从来没有设置过,-1表示当前连接不是主数据库,从SysConfig表获取的 + /// 当前版本,由ConfigConst.SysCurrentVersion转换的整数版本 + public void AfterInitSeed(SqlSugarScopeProvider dbProvider, long oldVerion, long currentVersion) + { + //比较版本号对数据库进行升级结构、种子数据等 + } +} + +/// +/// 测试InitDatas,Order越大,InitDatas执行越靠前 +/// +[AppStartup(1000)] +public class TestStartup : AppStartup +{ + /// + /// 初始化与升级数据,在初始化表结构之前调用 + /// + /// + /// 旧版本,0表示从来没有设置过,-1表示当前连接不是主数据库,从SysConfig表获取的 + /// 当前版本,由ConfigConst.SysCurrentVersion转换的整数版本 + public void BeforeInitTable(SqlSugarScopeProvider dbProvider, long oldVerion, long currentVersion) + { + //比较版本号对数据库进行升级结构、种子数据等 + } + /// + /// 初始化与升级数据,在初始化种子数据之后调用 + /// + /// + /// 旧版本,0表示从来没有设置过,-1表示当前连接不是主数据库,从SysConfig表获取的 + /// 当前版本,由ConfigConst.SysCurrentVersion转换的整数版本 + public void AfterInitSeed(SqlSugarScopeProvider dbProvider, long oldVerion, long currentVersion) + { + //比较版本号对数据库进行升级结构、种子数据等 + } } \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/Const/ConfigConst.cs b/Admin.NET/Admin.NET.Core/Const/ConfigConst.cs index b3104f1e..ef63591c 100644 --- a/Admin.NET/Admin.NET.Core/Const/ConfigConst.cs +++ b/Admin.NET/Admin.NET.Core/Const/ConfigConst.cs @@ -11,6 +11,15 @@ namespace Admin.NET.Core; /// public class ConfigConst { + /// + /// 系统版本code + /// + public const string SysVersion = "sys_version"; + /// + /// 当前系统版本值,标准版本号为 x.xx.xxxxxx。比如 1.01.250409,也可以是变体,比如 1.2.5 v1.2.5 + /// + public const string SysCurrentVersion = "1.01.000001"; + /// /// 演示环境 /// diff --git a/Admin.NET/Admin.NET.Core/SeedData/SysConfigSeedData.cs b/Admin.NET/Admin.NET.Core/SeedData/SysConfigSeedData.cs index 1b45f3b6..33cac5f6 100644 --- a/Admin.NET/Admin.NET.Core/SeedData/SysConfigSeedData.cs +++ b/Admin.NET/Admin.NET.Core/SeedData/SysConfigSeedData.cs @@ -39,6 +39,8 @@ public class SysConfigSeedData : ISqlSugarEntitySeedData new SysConfig{ Id=1300000000261, Name="密码历史记录验证", Code=ConfigConst.SysPasswordRecord, Value="False", SysFlag=YesNoEnum.Y, Remark="是否验证历史密码禁止再次使用", OrderNo=210, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2024-12-17 00:00:00") }, new SysConfig{ Id=1300000000271, Name="显示系统更新日志", Code=ConfigConst.SysUpgrade, Value="True", SysFlag=YesNoEnum.Y, Remark="是否显示系统更新日志", OrderNo=220, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2024-12-20 00:00:00") }, new SysConfig{ Id=1300000000281, Name="开启多语言切换", Code=ConfigConst.SysI18NSwitch, Value="True", SysFlag=YesNoEnum.Y, Remark="是否显示多语言切换按钮", OrderNo=230, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2024-12-20 00:00:00") }, + + new SysConfig{ Id=1300000000999, Name="系统版本", Code=ConfigConst.SysVersion, Value="0", SysFlag=YesNoEnum.Y, Remark= "系统版本,用于自动升级,请勿手动填写", OrderNo=1000, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") }, ]; } } \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarSetup.cs b/Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarSetup.cs index 37a0669c..327b0f72 100644 --- a/Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarSetup.cs +++ b/Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarSetup.cs @@ -352,6 +352,11 @@ public static class SqlSugarSetup }; } + private static int GetStartupOrder(Type type) + { + return !type.IsDefined(typeof(AppStartupAttribute), true) ? 0 : type.GetCustomAttribute(true).Order; + } + /// /// 初始化数据库 /// @@ -368,6 +373,46 @@ public static class SqlSugarSetup if (config.DbType != SqlSugar.DbType.Oracle) dbProvider.DbMaintenance.CreateDatabase(); } + // 扫描所有继承 AppStartup 的类 + var startups = App.EffectiveTypes + .Where(u => typeof(AppStartup).IsAssignableFrom(u) && u.IsClass && !u.IsAbstract && !u.IsGenericType) + .OrderByDescending(u => GetStartupOrder(u)); + //数据库前处理 + long oldVerion = 0, currentVersion = 0; + SysConfig versionCfg = null; + try + { + //获取旧版本号 + try + { + if (dbProvider.CurrentConnectionConfig.ConfigId.ToString() == SqlSugarConst.MainConfigId) + { + versionCfg = dbProvider.Queryable().Where(n => n.Code == ConfigConst.SysVersion).First(); + oldVerion = versionCfg != null ? CommonUtil.ConvertVersionToLong(versionCfg.Value) : 0; + } + else + { + oldVerion = -1; + } + } + catch (Exception ex) { } + finally + { + currentVersion = CommonUtil.ConvertVersionToLong(ConfigConst.SysCurrentVersion); + } + //执行 + foreach (var type in startups) + { + var startup = Activator.CreateInstance(type) as AppStartup; + var initDataMethod = type.GetMethod("BeforeInitTable"); + initDataMethod?.Invoke(startup, new[] { (object)dbProvider, oldVerion, currentVersion }); + } + } + catch (Exception ex) + { + Log.Information($"数据库前处理有错 {config.DbType} - {config.ConfigId} : {ex.Message}"); + } + // 初始化表结构 if (config.TableSettings.EnableInitTable) { @@ -408,6 +453,41 @@ public static class SqlSugarSetup // 初始化种子数据 if (config.SeedSettings.EnableInitSeed) InitSeedData(db, config); + + //数据后处理 + try + { + //执行后处理 + foreach (var type in startups) + { + var startup = Activator.CreateInstance(type) as AppStartup; + if (startup == null) continue; + var initDataMethod = type.GetMethod("AfterInitSeed"); + if (initDataMethod == null) continue; + initDataMethod?.Invoke(startup, new[] { (object)dbProvider, oldVerion, currentVersion }); + } + } + catch (Exception ex) + { + string errr = $"数据库后处理有错 {config.DbType} - {config.ConfigId} : {ex.Message}"; + Log.Information(errr); + Console.WriteLine(errr); + Console.WriteLine(ex.StackTrace); + } + finally + { + //最后更新版本 + if (dbProvider.CurrentConnectionConfig.ConfigId.ToString() == SqlSugarConst.MainConfigId) + { + IEnumerable cfgs = + [ + new SysConfig{ Id=1300000000999, Name="系统版本", Code=ConfigConst.SysVersion, Value=ConfigConst.SysCurrentVersion, SysFlag=YesNoEnum.Y, Remark= "系统版本,用于自动升级,请勿手动填写", OrderNo=1000, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") } + ]; + var storage = dbProvider.StorageableByObject(cfgs.ToList()).ToStorage(); + storage.AsInsertable.ExecuteCommand(); + storage.AsUpdateable.ExecuteCommand(); + } + } } /// diff --git a/Admin.NET/Admin.NET.Core/Utils/CommonUtil.cs b/Admin.NET/Admin.NET.Core/Utils/CommonUtil.cs index a2c62022..091916f6 100644 --- a/Admin.NET/Admin.NET.Core/Utils/CommonUtil.cs +++ b/Admin.NET/Admin.NET.Core/Utils/CommonUtil.cs @@ -39,7 +39,49 @@ public static class CommonUtil return Math.Abs(hash1 + (hash2 * 1566083941)); } } + /// + /// 将版本号转换为长整型,版本格式要求 x.xx.xxxxxx,比如 v1.2.5=>102000005 V3.10.42=>310000042 + /// + /// x.xx.xxxxxx + /// + /// + public static long ConvertVersionToLong(string version) + { + // 1. 移除所有字母(不区分大小写) + string noLetters = Regex.Replace(version, "[a-zA-Z]", ""); + // 2. 按 '.' 分割版本号 + string[] parts = noLetters.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); + + // 3. 确保至少有3部分,不足则补 "0" + if (parts.Length < 3) + { + Array.Resize(ref parts, 3); + for (int i = 0; i < parts.Length; i++) + { + parts[i] = string.IsNullOrEmpty(parts[i]) ? "0" : parts[i]; + } + } + + // 4. 格式化各部分: + // - part1: 至少1位(直接取) + // - part2: 补齐到2位(如 "2" → "02") + // - part3: 补齐到6位(如 "5" → "000005") + string part1 = parts[0]; + string part2 = parts[1].PadLeft(2, '0'); + string part3 = parts[2].PadLeft(6, '0'); + + // 5. 拼接所有部分并转换为 long + string combined = $"{part1}{part2}{part3}"; + if (long.TryParse(combined, out long result)) + { + return result; + } + else + { + throw new ArgumentException("版本号转换失败,结果超出 long 范围。"); + } + } /// /// 生成百分数 ///