在初始化表结构之前和初始化种子数据之后的反射回调,通过系统版本比较,方便系统内部的表结构、种子数据的平滑升级。
This commit is contained in:
parent
7d9c9e3c7e
commit
2032b8d3d5
@ -19,4 +19,52 @@ public class Startup : AppStartup
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// 初始化与升级数据,在初始化表结构之前调用
|
||||
/// </summary>
|
||||
/// <param name="dbProvider"></param>
|
||||
/// <param name="oldVerion">旧版本,0表示从来没有设置过,-1表示当前连接不是主数据库,从SysConfig表获取的</param>
|
||||
/// <param name="currentVersion">当前版本,由ConfigConst.SysCurrentVersion转换的整数版本</param>
|
||||
public void BeforeInitTable(SqlSugarScopeProvider dbProvider, long oldVerion, long currentVersion)
|
||||
{
|
||||
//比较版本号对数据库进行升级结构、种子数据等
|
||||
}
|
||||
/// <summary>
|
||||
/// 初始化与升级数据,在初始化种子数据之后调用
|
||||
/// </summary>
|
||||
/// <param name="dbProvider"></param>
|
||||
/// <param name="oldVerion">旧版本,0表示从来没有设置过,-1表示当前连接不是主数据库,从SysConfig表获取的</param>
|
||||
/// <param name="currentVersion">当前版本,由ConfigConst.SysCurrentVersion转换的整数版本</param>
|
||||
public void AfterInitSeed(SqlSugarScopeProvider dbProvider, long oldVerion, long currentVersion)
|
||||
{
|
||||
//比较版本号对数据库进行升级结构、种子数据等
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试InitDatas,Order越大,InitDatas执行越靠前
|
||||
/// </summary>
|
||||
[AppStartup(1000)]
|
||||
public class TestStartup : AppStartup
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化与升级数据,在初始化表结构之前调用
|
||||
/// </summary>
|
||||
/// <param name="dbProvider"></param>
|
||||
/// <param name="oldVerion">旧版本,0表示从来没有设置过,-1表示当前连接不是主数据库,从SysConfig表获取的</param>
|
||||
/// <param name="currentVersion">当前版本,由ConfigConst.SysCurrentVersion转换的整数版本</param>
|
||||
public void BeforeInitTable(SqlSugarScopeProvider dbProvider, long oldVerion, long currentVersion)
|
||||
{
|
||||
//比较版本号对数据库进行升级结构、种子数据等
|
||||
}
|
||||
/// <summary>
|
||||
/// 初始化与升级数据,在初始化种子数据之后调用
|
||||
/// </summary>
|
||||
/// <param name="dbProvider"></param>
|
||||
/// <param name="oldVerion">旧版本,0表示从来没有设置过,-1表示当前连接不是主数据库,从SysConfig表获取的</param>
|
||||
/// <param name="currentVersion">当前版本,由ConfigConst.SysCurrentVersion转换的整数版本</param>
|
||||
public void AfterInitSeed(SqlSugarScopeProvider dbProvider, long oldVerion, long currentVersion)
|
||||
{
|
||||
//比较版本号对数据库进行升级结构、种子数据等
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,15 @@ namespace Admin.NET.Core;
|
||||
/// </summary>
|
||||
public class ConfigConst
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统版本code
|
||||
/// </summary>
|
||||
public const string SysVersion = "sys_version";
|
||||
/// <summary>
|
||||
/// 当前系统版本值,标准版本号为 x.xx.xxxxxx。比如 1.01.250409,也可以是变体,比如 1.2.5 v1.2.5
|
||||
/// </summary>
|
||||
public const string SysCurrentVersion = "1.01.000001";
|
||||
|
||||
/// <summary>
|
||||
/// 演示环境
|
||||
/// </summary>
|
||||
|
||||
@ -39,6 +39,8 @@ public class SysConfigSeedData : ISqlSugarEntitySeedData<SysConfig>
|
||||
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") },
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -352,6 +352,11 @@ public static class SqlSugarSetup
|
||||
};
|
||||
}
|
||||
|
||||
private static int GetStartupOrder(Type type)
|
||||
{
|
||||
return !type.IsDefined(typeof(AppStartupAttribute), true) ? 0 : type.GetCustomAttribute<AppStartupAttribute>(true).Order;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化数据库
|
||||
/// </summary>
|
||||
@ -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<SysConfig>().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<SysConfig> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -39,7 +39,49 @@ public static class CommonUtil
|
||||
return Math.Abs(hash1 + (hash2 * 1566083941));
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 将版本号转换为长整型,版本格式要求 x.xx.xxxxxx,比如 v1.2.5=>102000005 V3.10.42=>310000042
|
||||
/// </summary>
|
||||
/// <param name="version">x.xx.xxxxxx</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
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 范围。");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 生成百分数
|
||||
/// </summary>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user