using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Serilog; using SqlSugar; using System.Data; using System.Reflection; using Wood.Cache; using Wood.Data.Repository.DataSeed; using Wood.Entity; using Wood.Entity.SystemManage; using Wood.Util; namespace Wood.Data.Repository { public static class SqlSugarDbContext { #region aop /// /// 配置Aop /// /// public static void SetDbAop(SqlSugarProvider db) { var config = db.CurrentConnectionConfig; // 设置超时时间 db.Ado.CommandTimeOut = GlobalContext.SystemConfig!.DBCommandTimeout; // 打印SQL语句 db.Aop.OnLogExecuting = (sql, pars) => { Log.Information("【执行SQL】" + UtilMethods.GetSqlString(config.DbType, sql, pars)); }; db.Aop.OnError = ex => { if (ex.Parametres == null) return; var pars = db.Utilities.SerializeObject(((SugarParameter[])ex.Parametres).ToDictionary(it => it.ParameterName, it => it.Value)); Log.Error("【错误SQL】" + UtilMethods.GetSqlString(config.DbType, ex.Sql, (SugarParameter[])ex.Parametres) + Environment.NewLine + pars); }; // 数据审计 db.Aop.DataExecuting = (oldValue, entityInfo) => { var user = GlobalContext.UserInfo; // 演示环境判断 if (entityInfo.OperationType == DataFilterType.InsertByObject) { // 主键(long类型)且没有值的---赋值雪花Id if (entityInfo.EntityColumnInfo.IsPrimarykey && entityInfo.EntityColumnInfo.PropertyInfo.PropertyType == typeof(long)) { var id = entityInfo.EntityColumnInfo.PropertyInfo.GetValue(entityInfo.EntityValue); if (id == null || (long)id == 0) entityInfo.SetValue(IdGeneratorHelper.Instance.GetId()); } if (entityInfo.PropertyName == "CreateTime") entityInfo.SetValue(DateTime.Now); if (user != null) { if (entityInfo.PropertyName == "TenantId") { var tenantId = ((dynamic)entityInfo.EntityValue).TenantId; if (tenantId == null || tenantId == 0) entityInfo.SetValue(user?.TenantId); } if (entityInfo.PropertyName == "CreateUserId") { var createUserId = ((dynamic)entityInfo.EntityValue).CreateUserId; if (createUserId == 0 || createUserId == null) entityInfo.SetValue(user?.UserId); } if (entityInfo.PropertyName == "CreateOrgId") { var createOrgId = ((dynamic)entityInfo.EntityValue).CreateOrgId; if (createOrgId == 0 || createOrgId == null) entityInfo.SetValue(user?.OrgId); } } } if (entityInfo.OperationType == DataFilterType.UpdateByObject) { if (entityInfo.PropertyName == "UpdateTime") entityInfo.SetValue(DateTime.Now); if (entityInfo.PropertyName == "UpdateUserId") entityInfo.SetValue(user?.UserId); } }; // 配置实体假删除过滤器 db.QueryFilter.AddTableFilter(u => u.IsDelete == false); var user = GlobalContext.UserInfo; // 超管 排除过滤器 if (user != null && user.IsSuperAdmin) return; // 配置租户过滤器 var tenantId = user?.TenantId; if (tenantId > 0) db.QueryFilter.AddTableFilter(u => u.TenantId == tenantId); // 配置用户机构(数据范围)过滤器 if (user != null) { if (!user.IsAdmin) { var icache = GlobalContext.ServiceProvider!.GetRequiredService(); var userCache = icache.GetCache(user.CacheKey); if (userCache != null) { //根据org列表筛选数据 if (userCache!.DataScopeType == DataScopeTypeEnum.Custom || userCache!.DataScopeType == DataScopeTypeEnum.MyOrg || userCache!.DataScopeType == DataScopeTypeEnum.MyOrgAndLower) db.QueryFilter.AddTableFilter(u => userCache.DataScopeOrgs.Contains(u.CreateOrgId!.Value)); //仅本人数据过滤器 //本人创建,而且在本人所属部门的数据 else if (userCache!.DataScopeType == DataScopeTypeEnum.MySelf) { db.QueryFilter.AddTableFilter(u => u.CreateOrgId!.Value == userCache.OrgId); db.QueryFilter.AddTableFilter(u => u.CreateUserId!.Value == userCache.Id); } } // else 全部数据不做筛选 } } // 其他配置自定义过滤器 } /// /// 开启库表差异化日志 /// /// /// public static void SetDbDiffLog(SqlSugarProvider db) { if (!GlobalContext.SystemConfig!.DBEnableDiffLog) return; //程序启动时注册 开启差异化记录 StaticConfig.CompleteInsertableFunc = StaticConfig.CompleteUpdateableFunc = StaticConfig.CompleteDeleteableFunc = obj => //it是具体的对象Updateable等是个object { //反射的方法可能多个就需要用GetMethods().Where if (obj.GetType().GenericTypeArguments[0].GetInterfaces().Any(it => it == typeof(IDiff))) { var method = obj.GetType().GetMethod("EnableDiffLogEvent"); method?.Invoke(obj, new object?[] { null }); } //技巧: //可以定义一个接口只要是这个接口的才走这个逻辑 //if(db.GetType().GenericTypeArguments[0].GetInterfaces().Any(it=>it==typeof(IDiff)) //可以根据类型写if //if(x.GetType().GenericTypeArguments[0] = typeof(Order)) { } }; db.Aop.OnDiffLogEvent = async u => { var tables = u.AfterData.Select(it => it.TableName).Distinct(); if(u.BeforeData!=null) tables = tables.Union(u.BeforeData.Select(it => it.TableName)).Distinct(); var logDiff = new LogDiffEntity { Tables = string.Join(", ", tables), // 操作后记录(字段描述、列名、值、表名、表描述) AfterData = JsonConvert.SerializeObject(u.AfterData), // 操作前记录(字段描述、列名、值、表名、表描述) BeforeData = (u.BeforeData != null ? JsonConvert.SerializeObject(u.BeforeData) : null), // 传进来的对象 BusinessData = JsonConvert.SerializeObject(u.BusinessData), // 枚举(insert、update、delete) DiffType = u.DiffType.ToString(), Sql = UtilMethods.GetSqlString(db.CurrentConnectionConfig.DbType, u.Sql, u.Parameters), Parameters = JsonConvert.SerializeObject(u.Parameters), Elapsed = u.Time == null ? 0 : (long)u.Time.Value.TotalMilliseconds }; //防止表格过多入库失败 if (logDiff.Tables.Length > 256) logDiff.Tables = logDiff.Tables.Substring(255); await db.Insertable(logDiff).ExecuteCommandAsync(); Log.Information($"*****差异日志开始*****{Environment.NewLine}{Environment.NewLine}{JsonConvert.SerializeObject(logDiff)}{Environment.NewLine}*****差异日志结束*****"); }; } #endregion #region 初始化 /// /// 初始化数据库 /// /// public static void InitDatabase(ISqlSugarClient db) { if (!GlobalContext.SystemConfig!.EnableInitDb) return; var dbProvider = db; // 创建数据库 if (db.CurrentConnectionConfig.DbType != SqlSugar.DbType.Oracle) { dbProvider.DbMaintenance.CreateDatabase(); } var tables = dbProvider.DbMaintenance.GetTableInfoList(); // 获取所有实体表-初始化表结构 var entityTypes = Assembly.GetAssembly(typeof(EntityBase))!.GetTypes().Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(SugarTable), false)).ToList(); if (!entityTypes.Any()) return; foreach (var entityType in entityTypes) { var sugarTable = entityType.GetCustomAttribute(); //只有首次创建的表需要初始化 //变更请通过手动处理 if (!tables.Any(it => string.Equals(it.Name, sugarTable!.TableName, StringComparison.OrdinalIgnoreCase))) { if (entityType.GetCustomAttribute() == null) dbProvider.CodeFirst.InitTables(entityType); else dbProvider.CodeFirst.SplitTables().InitTables(entityType); } } //第一次初始化数据 seed if (tables.Count < 1) UserDataSeed.InitData(db); } #endregion } }