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
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
|
|
}
|
|
}
|