You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

234 lines
10 KiB

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
/// <summary>
/// 配置Aop
/// </summary>
/// <param name="db"></param>
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<IDeletedFilter>(u => u.IsDelete == false);
var user = GlobalContext.UserInfo;
// 超管 排除过滤器
if (user != null && user.IsSuperAdmin)
return;
// 配置租户过滤器
var tenantId = user?.TenantId;
if (tenantId > 0)
db.QueryFilter.AddTableFilter<ITenantIdFilter>(u => u.TenantId == tenantId);
// 配置用户机构(数据范围)过滤器
if (user != null)
{
if (!user.IsAdmin)
{
var icache = GlobalContext.ServiceProvider!.GetRequiredService<ICache>();
var userCache = icache.GetCache<UserCache>(user.CacheKey);
if (userCache != null)
{
//根据org列表筛选数据
if (userCache!.DataScopeType == DataScopeTypeEnum.Custom ||
userCache!.DataScopeType == DataScopeTypeEnum.MyOrg ||
userCache!.DataScopeType == DataScopeTypeEnum.MyOrgAndLower)
db.QueryFilter.AddTableFilter<IOrgIdFilter>(u => userCache.DataScopeOrgs.Contains(u.CreateOrgId!.Value));
//仅本人数据过滤器
//本人创建,而且在本人所属部门的数据
else if (userCache!.DataScopeType == DataScopeTypeEnum.MySelf)
{
db.QueryFilter.AddTableFilter<IOrgIdFilter>(u => u.CreateOrgId!.Value == userCache.OrgId);
db.QueryFilter.AddTableFilter<ICreateUserIdFilter>(u => u.CreateUserId!.Value == userCache.Id);
}
}
// else 全部数据不做筛选
}
}
// 其他配置自定义过滤器
}
/// <summary>
/// 开启库表差异化日志
/// </summary>
/// <param name="db"></param>
/// <param name="config"></param>
public static void SetDbDiffLog(SqlSugarProvider db)
{
if (!GlobalContext.SystemConfig!.DBEnableDiffLog)
return;
//程序启动时注册 开启差异化记录
StaticConfig.CompleteInsertableFunc =
StaticConfig.CompleteUpdateableFunc =
StaticConfig.CompleteDeleteableFunc = obj => //it是具体的对象Updateable<T>等是个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 初始化
/// <summary>
/// 初始化数据库
/// </summary>
/// <param name="db"></param>
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<SugarTable>();
//只有首次创建的表需要初始化
//变更请通过手动处理
if (!tables.Any(it => string.Equals(it.Name, sugarTable!.TableName, StringComparison.OrdinalIgnoreCase)))
{
if (entityType.GetCustomAttribute<SplitTableAttribute>() == null)
dbProvider.CodeFirst.InitTables(entityType);
else
dbProvider.CodeFirst.SplitTables().InitTables(entityType);
}
}
//第一次初始化数据 seed
if (tables.Count < 1)
UserDataSeed.InitData(db);
}
#endregion
}
}