This commit is contained in:
owenchen committed 2026-08-26 13:22:07 +08:00
1 parent dc1c073ac6
commit 20abc22653
38 files changed
+143 -40

No files matched your search

@@ -27,6 +27,7 @@ namespace CloudBuilder.Core.DatabaseAccessor
private readonly IConfiguration configuration;
private readonly IHttpContextAccessor httpContextAccessor;
private FileLog fileLog;
public bool SkipAudit { get; set; } = false;
public MasterDbContext(DbContextOptions<MasterDbContext> options,
IEnumerable<IMasterRegistEntityType<ModelBuilder>> entityManagers,
@@ -67,6 +68,8 @@ namespace CloudBuilder.Core.DatabaseAccessor
public void SavingChangesEvent()
{
if (SkipAudit) return;
var entities = this.ChangeTracker.Entries()
.Where(u => (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added)).ToList();
if (entities == null || entities.Count < 1) return;
@@ -2,6 +2,7 @@
using CloudBuilder.Core.DependencyInjection.EFCore;
using CloudBuilder.Core.Policy;
using CloudBuilder.Core.Service;
using DocumentFormat.OpenXml.Spreadsheet;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.JsonWebTokens;
@@ -20,6 +21,8 @@ namespace CloudBuilder.Core.DatabaseAccessor
public IEnumerable<IMasterRegistEntityType<ModelBuilder>> _entityManagers;
private readonly IServiceProvider _serviceProvider;
private readonly IHttpContextAccessor httpContextAccessor;
private FileLog fileLog;
public bool SkipAudit { get; set; } = false;
public SecondaryDbContext(DbContextOptions<SecondaryDbContext> options,
IEnumerable<IMasterRegistEntityType<ModelBuilder>> entityManagers,
@@ -50,10 +53,14 @@ namespace CloudBuilder.Core.DatabaseAccessor
public void SavingChangesEvent()
{
if (SkipAudit) return;
var entities = this.ChangeTracker.Entries()
.Where(u => (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added)).ToList();
if (entities == null || entities.Count < 1) return;
DateTime now = DateTime.Now;
string uid = this.httpContextAccessor.HttpContext?.User?.Identity?.Name;
if (string.IsNullOrEmpty(uid))
@@ -115,6 +122,60 @@ namespace CloudBuilder.Core.DatabaseAccessor
}
}
}
foreach (var entity in entities)
{
var entityName = entity.Metadata.GetTableName() ?? entity.Entity.GetType().Name;
var state = entity.State;
// ======================================
// 1. 获取所有主键(支持复合主键)
// ======================================
var pkProps = entity.Properties
.Where(p => p.Metadata.IsPrimaryKey())
.ToList();
// 拼接 WHERE 条件:Id=1 AND TenantId=2
var whereClauses = pkProps
.Select(p => $"{p.Metadata.GetColumnName() ?? p.Metadata.Name} = '{p.CurrentValue?.ToString()?.Replace("'", "''")}'");
string whereSql = string.Join(" AND ", whereClauses);
string sqlLog = "";
// ======================================
// 修改 UPDATE
// ======================================
if (state == EntityState.Modified)
{
var setClauses = entity.Properties
.Where(p => p.IsModified) // 只记录真正修改的字段
.Select(p => $"{p.Metadata.GetColumnName() ?? p.Metadata.Name} = '{p.CurrentValue?.ToString()?.Replace("'", "''")}'");
string setSql = string.Join(", ", setClauses);
sqlLog = $"[{uid}][{now.ToString("yyyy-MM-dd HH:mm:ss")}]UPDATE {entityName} SET {setSql} WHERE {whereSql}";
}
// ======================================
// 新增 INSERT
// ======================================
else if (state == EntityState.Added)
{
var data = entity.Properties.ToDictionary(p => p.Metadata.GetColumnName() ?? p.Metadata.Name, p => p.CurrentValue);
var columns = string.Join(", ", data.Keys);
var values = string.Join(", ", data.Values.Select(v => $"'{v?.ToString()?.Replace("'", "''")}'"));
sqlLog = $"[{uid}][{now.ToString("yyyy-MM-dd HH:mm:ss")}]INSERT INTO {entityName} ({columns}) VALUES ({values})";
}
// ======================================
// 删除 DELETE
// ======================================
else if (state == EntityState.Deleted)
{
sqlLog = $"[{uid}][{now.ToString("yyyy-MM-dd HH:mm:ss")}]DELETE FROM {entityName} WHERE {whereSql}";
}
fileLog.WriteToFile(sqlLog);
}
}
protected override void OnModelCreating(ModelBuilder builder)
@@ -61,11 +61,24 @@ namespace CloudBuilder.Core.DependencyInjection.EFCore
.GetDbContextOptions(MasterDbContext.MASTER_DB_CONTEXT)
.ConnectionString;
opts.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
if (builder.CloudBuilderOptions.GetDbContextOptions(MasterDbContext.MASTER_DB_CONTEXT).DatabaseType == DatabaseType.MySql)
opts.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
else
opts.UseSqlServer(connStr);
});
services.AddDbContext<SecondaryDbContext>(opts =>
opts.UseSqlServer(builder.CloudBuilderOptions.GetDbContextOptions(SecondaryDbContext.SECONDARY_DB_CONTEXT).ConnectionString));
{
var connStr = builder.CloudBuilderOptions
.GetDbContextOptions(SecondaryDbContext.SECONDARY_DB_CONTEXT)
.ConnectionString;
if (builder.CloudBuilderOptions.GetDbContextOptions(SecondaryDbContext.SECONDARY_DB_CONTEXT).DatabaseType == DatabaseType.MySql)
opts.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
else
opts.UseSqlServer(connStr);
}
);
// services.AddDbContext<MasterDbContext>(opts =>
//opts.UseSqlServer(builder.CloudBuilderOptions.GetDbContextOptions(MasterDbContext.MASTER_DB_CONTEXT).ConnectionString));
@@ -286,7 +286,7 @@ namespace CloudBuilder.Security.Service
if (maps == null || maps.Length == 0) return;
int i = 1;
foreach (SecurityFunctionMapViewEntity map in maps.OrderBy(x => x.Orderby).ToArray())
foreach (SecurityFunctionMapViewEntity map in maps.ToArray())
{
repositoryMap.InsertNow(new SecurityFunctionMapEntity()
{
@@ -1,4 +1,5 @@
using CloudBuilder.Core.DatabaseAccessor.Entity;
using CloudBuilder.Core.DatabaseAccessor;
using CloudBuilder.Core.DatabaseAccessor.Entity;
using CloudBuilder.Core.Service;
using CloudBuilder.Security.Data;
using CloudBuilder.Security.Entity;
@@ -100,7 +101,7 @@ namespace CloudBuilder.Security.Service
repositorySecurityGeneratorNumber.ChangeSecondaryDatabase();
var locales= repository.DetachedEntities.ToArray();
var locales = repository.DetachedEntities.ToArray();
var SecurityUsers = repositorySecurityUser.DetachedEntities.ToArray();
var SecurityUserActors = repositorySecurityUserActor.DetachedEntities.ToArray();
var SecurityActors = repositorySecurityActor.DetachedEntities.ToArray();
@@ -132,8 +133,14 @@ namespace CloudBuilder.Security.Service
repositorySecurityMaster.ChangeMasterDatabase();
repositorySecurityGeneratorNumber.ChangeMasterDatabase();
repository.ExecuteNonQuery("TRUNCATE TABLE " + LocaleEntity.DB_NAME_LOCALE);
// 取得 MasterDbContext,開啟跳審計,保留原始 CreatedBy / UpdatedBy
var secDbCtx = repository.GetDbContext() as MasterDbContext;
if (secDbCtx != null)
{
secDbCtx.SkipAudit = true;
}
repository.ExecuteNonQuery("TRUNCATE TABLE " + LocaleEntity.DB_NAME_LOCALE);
repository.ExecuteNonQuery("TRUNCATE TABLE " + SecurityUserEntity.DB_NAME_SECURITY_USER);
repository.ExecuteNonQuery("TRUNCATE TABLE " + SecurityActorEntity.DB_NAME_SECURITY_ACTOR);
repository.ExecuteNonQuery("TRUNCATE TABLE " + SecurityUserActorEntity.DB_NAME_SECURITY_USER_ACTOR);
@@ -148,7 +155,7 @@ namespace CloudBuilder.Security.Service
repository.ExecuteNonQuery("TRUNCATE TABLE " + SecurityFunctionMapEntity.DB_NAME_SECURITY_FUNCTION_MAP);
repository.ExecuteNonQuery("TRUNCATE TABLE " + SecurityMasterEntity.DB_NAME_SECURITY_MASTER);
repository.ExecuteNonQuery("TRUNCATE TABLE " + SecurityGeneratorNumberEntity.DB_NAME_SECURITY_GENERATOR_NUMBER);
repository.InsertNow(locales);
repositorySecurityUser.InsertNow(SecurityUsers);
repositorySecurityUserActor.InsertNow(SecurityUserActors);
@@ -163,7 +170,26 @@ namespace CloudBuilder.Security.Service
repositorySecurityFunction.InsertNow(SecurityFunctions);
repositorySecurityFunctionMap.InsertNow(SecurityFunctionMaps);
repositorySecurityMaster.InsertNow(SecurityMasters);
//Copy 到 MySQL 不需要
if (secDbCtx.Database.ProviderName.Contains("SqlServer"))
{
repository.ExecuteNonQuery("SET IDENTITY_INSERT " + SecurityGeneratorNumberEntity.DB_NAME_SECURITY_GENERATOR_NUMBER + " ON;");
}
repositorySecurityGeneratorNumber.InsertNow(SecurityGeneratorNumbers);
//Copy 到 MySQL 不需要
if (secDbCtx.Database.ProviderName.Contains("SqlServer"))
{
repository.ExecuteNonQuery("SET IDENTITY_INSERT " + SecurityGeneratorNumberEntity.DB_NAME_SECURITY_GENERATOR_NUMBER + " OFF;");
}
// ⚠️務必關閉 SkipAudit,避免後續正常業務失效
if (secDbCtx != null)
{
secDbCtx.SkipAudit = false;
}
}
}
}
@@ -56,7 +56,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_VALUE = "value";
public const string DB_ORDER_BY = "order_by";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static LocaleEntity GetInstance(string providerName)
{
@@ -49,7 +49,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_ACTOR_LOCAL_NAME = "actor_local_name";
public const string DB_ACTOR_ENG_NAME = "actor_eng_name";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityActorEntity GetInstance(string providerName)
{
@@ -44,7 +44,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_ACTOR_NAME = "actor_name";
public const string DB_GROUP_NAME = "group_name";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityActorGroupEntity GetInstance(string providerName)
{
@@ -36,7 +36,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_GROUP_NAME = "group_name";
public const string DB_GROUP_LOCAL_NAME = "group_local_name";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityActorGroupViewEntity GetInstance(string providerName)
{
@@ -69,7 +69,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_ICON = "icon";
public const string DB_PAGE_NAME = "page_name";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityFunctionEntity GetInstance(string providerName)
{
@@ -48,7 +48,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_FUNCTION_NAME_SON = "function_name_son";
public const string DB_ORDERBY = "orderby";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityFunctionMapEntity GetInstance(string providerName)
{
@@ -44,7 +44,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_SON_FUNCTION_LOCAL_NAME = "son_function_local_name";
public const string DB_SON_PAGE_NAME = "son_page_name";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityFunctionMapViewEntity GetInstance(string providerName)
{
@@ -70,7 +70,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_LAST_GENERATOR_DATE = "last_generator_date";
public const string DB_NEXT_ID = "next_id";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityGeneratorNumberEntity GetInstance(string providerName)
{
@@ -49,7 +49,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_GROUP_LOCAL_NAME = "group_local_name";
public const string DB_GROUP_ENG_NAME = "group_eng_name";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityGroupEntity GetInstance(string providerName)
{
@@ -64,7 +64,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_AMEND_INDC = "amend_indc";
public const string DB_DELETE_INDC = "delete_indc";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityGroupPermissionDependentEntity GetInstance(string providerName)
{
@@ -60,7 +60,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_DEPENDENT_DETAIL_DESCRIPTION = "dependent_detail_description";
public const string DB_DEPENDENT = "dependent";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityGroupPermissionDependentViewEntity GetInstance(string providerName)
{
@@ -64,7 +64,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_DELETE_INDC = "delete_indc";
public const string DB_DEPENDENT = "dependent";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityGroupPermissionEntity GetInstance(string providerName)
{
@@ -52,7 +52,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_DEPENDENT = "dependent";
public const string DB_PERMISSION_DESCRIPTION = "permission_description";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityGroupPermissionViewEntity GetInstance(string providerName)
{
@@ -68,7 +68,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_SECURITY_USER_UPD = "security_user_upd";
public const string DB_SECURITY_USER_ACTOR_UPD = "security_user_actor_upd";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityInitializerTickViewEntity GetInstance(string providerName)
{
@@ -48,7 +48,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_PKEY_ID = "pkey_id";
public const string DB_LOCKED_BY_ACTOR = "locked_by_actor";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityLockEntity GetInstance(string providerName)
{
@@ -72,7 +72,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_VALID_INDC = "valid_indc";
public const string DB_REMARK = "remark";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityMasterEntity GetInstance(string providerName)
{
@@ -52,7 +52,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_DEPENDENT_DETAIL_NAME = "dependent_detail_name";
public const string DB_DEPENDENT_DETAIL_DESCRIPTION = "dependent_detail_description";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityPermissionDependentEntity GetInstance(string providerName)
{
@@ -53,7 +53,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_DESCRIPTION = "description";
public const string DB_DELEGATE_INDC = "delegate_indc";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityPermissionEntity GetInstance(string providerName)
{
@@ -44,7 +44,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_PERMISSION_NAME = "permission_name";
public const string DB_FUNCTION_NAME = "function_name";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityPermissionFunctionMapEntity GetInstance(string providerName)
{
@@ -32,7 +32,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_FUNCTION_NAME = "function_name";
public const string DB_PAGE_NAME = "page_name";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityPermissionFunctionMapViewEntity GetInstance(string providerName)
{
@@ -40,7 +40,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_CREATED_DATETIME = "created_datetime";
public const string DB_DEPENDENT = "dependent";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityPermissionViewEntity GetInstance(string providerName)
{
@@ -54,7 +54,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_FIELD_NAME = "field_name";
public const string DB_DESCRIPTION = "description";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityTableDescriptionEntity GetInstance(string providerName)
{
@@ -44,7 +44,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_USER_NAME = "user_name";
public const string DB_ACTOR_NAME = "actor_name";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityUserActorEntity GetInstance(string providerName)
{
@@ -40,7 +40,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_ACTOR_NAME = "actor_name";
public const string DB_ACTOR_LOCAL_NAME = "actor_local_name";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityUserActorViewEntity GetInstance(string providerName)
{
@@ -56,7 +56,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_START_DATETIME = "start_datetime";
public const string DB_END_DATETIME = "end_datetime";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityUserDelegatedPermissionEntity GetInstance(string providerName)
{
@@ -173,7 +173,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_BIOMETRIC_ENROLLED_AT = "biometric_enrolled_at";
public const string DB_BIOMETRIC_LAST_USED_AT = "biometric_last_used_at";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityUserEntity GetInstance(string providerName)
{
@@ -54,7 +54,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_AGENT_USER_NAME = "agent_user_name";
public const string DB_IP_ADDRESS = "ip_address";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityUserLoginLogEntity GetInstance(string providerName)
{
@@ -48,7 +48,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_PREFERENCE_KEY = "preference_key";
public const string DB_PREFERENCE = "preference";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityUserPreferenceEntity GetInstance(string providerName)
{
@@ -44,7 +44,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_ACTOR_NAME = "actor_name";
public const string DB_ACTOR_LOCAL_NAME = "actor_local_name";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityUserViewEntity GetInstance(string providerName)
{
@@ -52,7 +52,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_REFRESH_TOKEN = "refresh_token";
public const string DB_REFRESH_TOKEN_REFRESHED_TIME = "refresh_token_refreshed_time";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityUserWebLoginEntity GetInstance(string providerName)
{
@@ -56,7 +56,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_PREFERENCE = "preference";
public const string DB_DEFAULT_INDC = "default_indc";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SecurityUserWebPagePreferenceEntity GetInstance(string providerName)
{
@@ -44,7 +44,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_PK_NAME = "pk_name";
public const string DB_PK = "pk";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SysTablePkeyViewEntity GetInstance(string providerName)
{
@@ -80,7 +80,7 @@ namespace CloudBuilder.Security.Entity
public const string DB_IS_IDENTITY = "is_identity";
public const string DB_COLID = "colid";
public string ProviderName { get; set; }
private string ProviderName { get; set; }
public static SysTableSchemaViewEntity GetInstance(string providerName)
{