mirror of
https://github.com/anjoy8/Blog.Core.git
synced 2024-09-20 23:48:27 +08:00
✨ 增加数据库管理
This commit is contained in:
parent
8183be9d58
commit
e9f1ef5c01
|
@ -106,6 +106,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Controllers\Systems\" />
|
||||
<Folder Include="wwwroot\BlogCore.Data.excel\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -1957,6 +1957,11 @@
|
|||
找不到指定资源
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Blog.Core.Model.Systems.DataBase.DataBaseReadType">
|
||||
<summary>
|
||||
数据库读取类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Blog.Core.Model.TableModel`1">
|
||||
<summary>
|
||||
表格数据,支持分页
|
||||
|
|
|
@ -1299,6 +1299,46 @@
|
|||
<param name="id"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:Blog.Core.Api.Controllers.Systems.DataBaseController">
|
||||
<summary>
|
||||
数据库管理
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Blog.Core.Api.Controllers.Systems.DataBaseController.GetAllConfig">
|
||||
<summary>
|
||||
获取库配置
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Blog.Core.Api.Controllers.Systems.DataBaseController.GetTableInfoList(System.String,Blog.Core.Model.Systems.DataBase.DataBaseReadType)">
|
||||
<summary>
|
||||
获取表信息
|
||||
</summary>
|
||||
<param name="configId">配置Id</param>
|
||||
<param name="readType">读取类型</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Blog.Core.Api.Controllers.Systems.DataBaseController.GetColumnInfosByTableName(System.String,System.String,Blog.Core.Model.Systems.DataBase.DataBaseReadType)">
|
||||
<summary>
|
||||
获取表字段
|
||||
</summary>
|
||||
<param name="tableName">表名</param>
|
||||
<param name="configId">ConfigId</param>
|
||||
<param name="readType">读取类型</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Blog.Core.Api.Controllers.Systems.DataBaseController.PutTableEditRemark(Blog.Core.Model.Systems.DataBase.EditTableInput)">
|
||||
<summary>
|
||||
编辑表备注
|
||||
</summary>
|
||||
<param name="input"></param>
|
||||
</member>
|
||||
<member name="M:Blog.Core.Api.Controllers.Systems.DataBaseController.PutColumnEditRemark(Blog.Core.Model.Systems.DataBase.EditColumnInput)">
|
||||
<summary>
|
||||
编辑列备注
|
||||
</summary>
|
||||
<param name="input"></param>
|
||||
</member>
|
||||
<member name="T:Blog.Core.Api.Controllers.Tenant.TenantByDbController">
|
||||
<summary>
|
||||
多租户-多库方案 测试
|
||||
|
|
|
@ -4,82 +4,85 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Blog.Core.Controllers
|
||||
{
|
||||
public class BaseApiController : Controller
|
||||
{
|
||||
[NonAction]
|
||||
public MessageModel<T> Success<T>(T data, string msg = "成功")
|
||||
{
|
||||
return new MessageModel<T>()
|
||||
{
|
||||
success = true,
|
||||
msg = msg,
|
||||
response = data,
|
||||
};
|
||||
}
|
||||
// [NonAction]
|
||||
//public MessageModel<T> Success<T>(T data, string msg = "成功",bool success = true)
|
||||
//{
|
||||
// return new MessageModel<T>()
|
||||
// {
|
||||
// success = success,
|
||||
// msg = msg,
|
||||
// response = data,
|
||||
// };
|
||||
//}
|
||||
[NonAction]
|
||||
public MessageModel Success(string msg = "成功")
|
||||
{
|
||||
return new MessageModel()
|
||||
{
|
||||
success = true,
|
||||
msg = msg,
|
||||
response = null,
|
||||
};
|
||||
}
|
||||
[NonAction]
|
||||
public MessageModel<string> Failed(string msg = "失败", int status = 500)
|
||||
{
|
||||
return new MessageModel<string>()
|
||||
{
|
||||
success = false,
|
||||
status = status,
|
||||
msg = msg,
|
||||
response = null,
|
||||
};
|
||||
}
|
||||
[NonAction]
|
||||
public MessageModel<T> Failed<T>(string msg = "失败", int status = 500)
|
||||
{
|
||||
return new MessageModel<T>()
|
||||
{
|
||||
success = false,
|
||||
status = status,
|
||||
msg = msg,
|
||||
response = default,
|
||||
};
|
||||
}
|
||||
[NonAction]
|
||||
public MessageModel<PageModel<T>> SuccessPage<T>(int page, int dataCount, int pageSize, List<T> data, int pageCount, string msg = "获取成功")
|
||||
{
|
||||
public class BaseApiController : Controller
|
||||
{
|
||||
[NonAction]
|
||||
public MessageModel<T> Success<T>(T data, string msg = "成功")
|
||||
{
|
||||
return new MessageModel<T>()
|
||||
{
|
||||
success = true,
|
||||
msg = msg,
|
||||
response = data,
|
||||
};
|
||||
}
|
||||
|
||||
return new MessageModel<PageModel<T>>()
|
||||
{
|
||||
success = true,
|
||||
msg = msg,
|
||||
response = new PageModel<T>(page, dataCount, pageSize, data)
|
||||
// [NonAction]
|
||||
//public MessageModel<T> Success<T>(T data, string msg = "成功",bool success = true)
|
||||
//{
|
||||
// return new MessageModel<T>()
|
||||
// {
|
||||
// success = success,
|
||||
// msg = msg,
|
||||
// response = data,
|
||||
// };
|
||||
//}
|
||||
[NonAction]
|
||||
public MessageModel Success(string msg = "成功")
|
||||
{
|
||||
return new MessageModel()
|
||||
{
|
||||
success = true,
|
||||
msg = msg,
|
||||
response = null,
|
||||
};
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public MessageModel<string> Failed(string msg = "失败", int status = 500)
|
||||
{
|
||||
return new MessageModel<string>()
|
||||
{
|
||||
success = false,
|
||||
status = status,
|
||||
msg = msg,
|
||||
response = null,
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
[NonAction]
|
||||
public MessageModel<PageModel<T>> SuccessPage<T>(PageModel<T> pageModel, string msg = "获取成功")
|
||||
{
|
||||
[NonAction]
|
||||
public MessageModel<T> Failed<T>(string msg = "失败", int status = 500)
|
||||
{
|
||||
return new MessageModel<T>()
|
||||
{
|
||||
success = false,
|
||||
status = status,
|
||||
msg = msg,
|
||||
response = default,
|
||||
};
|
||||
}
|
||||
|
||||
return new MessageModel<PageModel<T>>()
|
||||
{
|
||||
success = true,
|
||||
msg = msg,
|
||||
response = pageModel
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
[NonAction]
|
||||
public MessageModel<PageModel<T>> SuccessPage<T>(int page, int dataCount, int pageSize, List<T> data,
|
||||
int pageCount, string msg = "获取成功")
|
||||
{
|
||||
return new MessageModel<PageModel<T>>()
|
||||
{
|
||||
success = true,
|
||||
msg = msg,
|
||||
response = new PageModel<T>(page, dataCount, pageSize, data)
|
||||
};
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public MessageModel<PageModel<T>> SuccessPage<T>(PageModel<T> pageModel, string msg = "获取成功")
|
||||
{
|
||||
return new MessageModel<PageModel<T>>()
|
||||
{
|
||||
success = true,
|
||||
msg = msg,
|
||||
response = pageModel
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
188
Blog.Core.Api/Controllers/Systems/DataBaseController.cs
Normal file
188
Blog.Core.Api/Controllers/Systems/DataBaseController.cs
Normal file
|
@ -0,0 +1,188 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Blog.Core.Common;
|
||||
using Blog.Core.Common.DB;
|
||||
using Blog.Core.Controllers;
|
||||
using Blog.Core.Model;
|
||||
using Blog.Core.Model.Models;
|
||||
using Blog.Core.Model.Systems.DataBase;
|
||||
using Blog.Core.Model.Tenants;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
|
||||
namespace Blog.Core.Api.Controllers.Systems;
|
||||
|
||||
/// <summary>
|
||||
/// 数据库管理
|
||||
/// </summary>
|
||||
[Route("api/Systems/[controller]/[action]")]
|
||||
[ApiController]
|
||||
[Authorize(Permissions.Name)]
|
||||
public class DataBaseController : BaseApiController
|
||||
{
|
||||
private readonly ISqlSugarClient _db;
|
||||
|
||||
public DataBaseController(ISqlSugarClient db)
|
||||
{
|
||||
_db = db;
|
||||
}
|
||||
|
||||
[return: NotNull]
|
||||
public ISqlSugarClient GetTenantDb(string configId)
|
||||
{
|
||||
if (!_db.AsTenant().IsAnyConnection(configId))
|
||||
{
|
||||
var tenant = _db.Queryable<SysTenant>().WithCache()
|
||||
.Where(s => s.TenantType == TenantTypeEnum.Db)
|
||||
.Where(s => s.ConfigId == configId)
|
||||
.First();
|
||||
if (tenant != null)
|
||||
{
|
||||
_db.AsTenant().AddConnection(tenant.GetConnectionConfig());
|
||||
}
|
||||
}
|
||||
|
||||
var db = _db.AsTenant().GetConnectionScope(configId);
|
||||
if (db is null)
|
||||
{
|
||||
throw new ApplicationException("无效的数据库配置");
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取库配置
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<MessageModel<List<DatabaseOutput>>> GetAllConfig()
|
||||
{
|
||||
//增加多租户的连接
|
||||
var allConfigs = new List<ConnectionConfig>(BaseDBConfig.AllConfigs);
|
||||
var tenants = await _db.Queryable<SysTenant>().WithCache()
|
||||
.Where(s => s.TenantType == TenantTypeEnum.Db)
|
||||
.ToListAsync();
|
||||
if (tenants.Any())
|
||||
{
|
||||
allConfigs.AddRange(tenants.Select(tenant => tenant.GetConnectionConfig()));
|
||||
}
|
||||
|
||||
var configs = await Task.FromResult(allConfigs);
|
||||
return Success(configs.Adapt<List<DatabaseOutput>>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取表信息
|
||||
/// </summary>
|
||||
/// <param name="configId">配置Id</param>
|
||||
/// <param name="readType">读取类型</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public MessageModel<List<DbTableInfo>> GetTableInfoList(string configId,
|
||||
DataBaseReadType readType = DataBaseReadType.Db)
|
||||
{
|
||||
if (configId.IsNullOrEmpty())
|
||||
{
|
||||
configId = MainDb.CurrentDbConnId;
|
||||
}
|
||||
|
||||
var provider = GetTenantDb(configId);
|
||||
List<DbTableInfo> data = null;
|
||||
switch (readType)
|
||||
{
|
||||
case DataBaseReadType.Db:
|
||||
data = provider.DbMaintenance.GetTableInfoList(false);
|
||||
break;
|
||||
case DataBaseReadType.Entity:
|
||||
if (EntityUtility.TenantEntitys.TryGetValue(configId, out var types))
|
||||
{
|
||||
data = types.Select(s => provider.EntityMaintenance.GetEntityInfo(s))
|
||||
.Select(s => new {Name = s.DbTableName, Description = s.TableDescription})
|
||||
.Adapt<List<DbTableInfo>>();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return Success(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取表字段
|
||||
/// </summary>
|
||||
/// <param name="tableName">表名</param>
|
||||
/// <param name="configId">ConfigId</param>
|
||||
/// <param name="readType">读取类型</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public MessageModel<List<DbColumnInfoOutput>> GetColumnInfosByTableName(string tableName, string configId = null,
|
||||
DataBaseReadType readType = DataBaseReadType.Db)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(tableName))
|
||||
return Failed<List<DbColumnInfoOutput>>("表名不能为空");
|
||||
|
||||
if (configId.IsNullOrEmpty())
|
||||
{
|
||||
configId = MainDb.CurrentDbConnId;
|
||||
}
|
||||
|
||||
List<DbColumnInfoOutput> data = null;
|
||||
var provider = GetTenantDb(configId);
|
||||
switch (readType)
|
||||
{
|
||||
case DataBaseReadType.Db:
|
||||
data = provider.DbMaintenance.GetColumnInfosByTableName(tableName, false)
|
||||
.Adapt<List<DbColumnInfoOutput>>();
|
||||
break;
|
||||
case DataBaseReadType.Entity:
|
||||
if (EntityUtility.TenantEntitys.TryGetValue(configId, out var types))
|
||||
{
|
||||
var type = types.FirstOrDefault(s => s.Name == tableName);
|
||||
data = provider.EntityMaintenance.GetEntityInfo(type).Columns.Adapt<List<DbColumnInfoOutput>>();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return Success(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑表备注
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
[HttpPut]
|
||||
public MessageModel PutTableEditRemark([FromBody] EditTableInput input)
|
||||
{
|
||||
var provider = GetTenantDb(input.ConfigId);
|
||||
if (provider.DbMaintenance.IsAnyTableRemark(input.TableName))
|
||||
{
|
||||
provider.DbMaintenance.DeleteTableRemark(input.TableName);
|
||||
}
|
||||
|
||||
provider.DbMaintenance.AddTableRemark(input.TableName, input.Description);
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑列备注
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
[HttpPut]
|
||||
public MessageModel PutColumnEditRemark([FromBody] EditColumnInput input)
|
||||
{
|
||||
var provider = GetTenantDb(input.ConfigId);
|
||||
if (provider.DbMaintenance.IsAnyColumnRemark(input.DbColumnName, input.TableName))
|
||||
{
|
||||
provider.DbMaintenance.DeleteColumnRemark(input.DbColumnName, input.TableName);
|
||||
}
|
||||
|
||||
provider.DbMaintenance.AddColumnRemark(input.DbColumnName, input.TableName, input.ColumnDescription);
|
||||
|
||||
return Success();
|
||||
}
|
||||
}
|
|
@ -18,6 +18,9 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Magicodes.IE.Excel" Version="2.6.4" />
|
||||
<PackageReference Include="InitQ" Version="1.0.0.12" />
|
||||
<PackageReference Include="log4net" Version="2.0.15" />
|
||||
<PackageReference Include="Mapster" Version="7.3.0" />
|
||||
<PackageReference Include="Mapster.Core" Version="1.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
|
||||
|
|
|
@ -3,18 +3,23 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SqlSugar;
|
||||
|
||||
namespace Blog.Core.Common.DB
|
||||
{
|
||||
public class BaseDBConfig
|
||||
{
|
||||
public static readonly List<ConnectionConfig> AllConfigs = new(); //所有库配置
|
||||
public static readonly List<SlaveConnectionConfig> AllSlaveConfigs = new(); //从库配置
|
||||
public static List<ConnectionConfig> ValidConfig = new(); //有效的库连接(除去Log库)
|
||||
public static ConnectionConfig LogConfig; //日志库
|
||||
|
||||
/* 之前的单库操作已经删除,如果想要之前的代码,可以查看我的GitHub的历史记录
|
||||
* 目前是多库操作,默认加载的是appsettings.json设置为true的第一个db连接。
|
||||
*/
|
||||
public static (List<MutiDBOperate> allDbs, List<MutiDBOperate> slaveDbs) MutiConnectionString => MutiInitConn();
|
||||
public static List<ConnectionConfig> AllConfig = new(); //所有的库连接
|
||||
public static List<ConnectionConfig> ValidConfig = new(); //有效的库连接(除去Log库)
|
||||
public static ConnectionConfig LogConfig; //日志库
|
||||
|
||||
|
||||
|
||||
private static string DifDBConnOfSecurity(params string[] conn)
|
||||
{
|
||||
|
@ -54,7 +59,7 @@ namespace Blog.Core.Common.DB
|
|||
List<MutiDBOperate> listdatabaseSlaveDB = new List<MutiDBOperate>(); //从库
|
||||
|
||||
// 单库,且不开启读写分离,只保留一个
|
||||
if (!AppSettings.app(new string[] { "CQRSEnabled" }).ObjToBool() && !AppSettings.app(new string[] { "MutiDBEnabled" }).ObjToBool())
|
||||
if (!AppSettings.app(new string[] {"CQRSEnabled"}).ObjToBool() && !AppSettings.app(new string[] {"MutiDBEnabled"}).ObjToBool())
|
||||
{
|
||||
if (listdatabase.Count == 1)
|
||||
{
|
||||
|
@ -62,7 +67,7 @@ namespace Blog.Core.Common.DB
|
|||
}
|
||||
else
|
||||
{
|
||||
var dbFirst = listdatabase.FirstOrDefault(d => d.ConnId == AppSettings.app(new string[] { "MainDB" }).ObjToString());
|
||||
var dbFirst = listdatabase.FirstOrDefault(d => d.ConnId == AppSettings.app(new string[] {"MainDB"}).ObjToString());
|
||||
if (dbFirst == null)
|
||||
{
|
||||
dbFirst = listdatabase.FirstOrDefault();
|
||||
|
@ -75,11 +80,11 @@ namespace Blog.Core.Common.DB
|
|||
|
||||
|
||||
// 读写分离,且必须是单库模式,获取从库
|
||||
if (AppSettings.app(new string[] { "CQRSEnabled" }).ObjToBool() && !AppSettings.app(new string[] { "MutiDBEnabled" }).ObjToBool())
|
||||
if (AppSettings.app(new string[] {"CQRSEnabled"}).ObjToBool() && !AppSettings.app(new string[] {"MutiDBEnabled"}).ObjToBool())
|
||||
{
|
||||
if (listdatabase.Count > 1)
|
||||
{
|
||||
listdatabaseSlaveDB = listdatabase.Where(d => d.ConnId != AppSettings.app(new string[] { "MainDB" }).ObjToString()).ToList();
|
||||
listdatabaseSlaveDB = listdatabase.Where(d => d.ConnId != AppSettings.app(new string[] {"MainDB"}).ObjToString()).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
53
Blog.Core.Common/DB/EntityUtility.cs
Normal file
53
Blog.Core.Common/DB/EntityUtility.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using Blog.Core.Common.Extensions;
|
||||
using Blog.Core.Model;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Blog.Core.Common.DB;
|
||||
|
||||
public class EntityUtility
|
||||
{
|
||||
private static readonly Lazy<Dictionary<string, List<Type>>> _tenantEntitys = new(() =>
|
||||
{
|
||||
Dictionary<string, List<Type>> dic = new Dictionary<string, List<Type>>();
|
||||
var assembly = Assembly.Load("Blog.Core.Model");
|
||||
//扫描 实体
|
||||
foreach (var type in assembly.GetTypes().Where(s => s.IsClass && !s.IsAbstract))
|
||||
{
|
||||
var tenant = type.GetCustomAttribute<TenantAttribute>();
|
||||
if (tenant != null)
|
||||
{
|
||||
dic.TryAdd(tenant.configId.ToString(), type);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type.IsSubclassOf(typeof(RootEntityTkey<>)))
|
||||
{
|
||||
dic.TryAdd(MainDb.CurrentDbConnId, type);
|
||||
continue;
|
||||
}
|
||||
|
||||
var table = type.GetCustomAttribute<SugarTable>();
|
||||
if (table != null)
|
||||
{
|
||||
dic.TryAdd(MainDb.CurrentDbConnId, type);
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug.Assert(type.Namespace != null, "type.Namespace != null");
|
||||
if (type.Namespace.StartsWith("Blog.Core.Model.Models"))
|
||||
{
|
||||
dic.TryAdd(MainDb.CurrentDbConnId, type);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return dic;
|
||||
});
|
||||
|
||||
public static Dictionary<string, List<Type>> TenantEntitys => _tenantEntitys.Value;
|
||||
}
|
18
Blog.Core.Common/Extensions/DictionaryExtensions.cs
Normal file
18
Blog.Core.Common/Extensions/DictionaryExtensions.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Blog.Core.Common.Extensions;
|
||||
|
||||
public static class DictionaryExtensions
|
||||
{
|
||||
public static void TryAdd<TKey, TValue>(this IDictionary<TKey, List<TValue>> dic, TKey key, TValue value)
|
||||
{
|
||||
if (dic.TryGetValue(key, out var old))
|
||||
{
|
||||
old.Add(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
dic.Add(key, new List<TValue> {value});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,212 +14,229 @@ using System.Linq;
|
|||
using System.Security.Claims;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Blog.Core.Model.Models;
|
||||
|
||||
namespace Blog.Core.AuthHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 权限授权处理器
|
||||
/// </summary>
|
||||
public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证方案提供对象
|
||||
/// </summary>
|
||||
public IAuthenticationSchemeProvider Schemes { get; set; }
|
||||
/// <summary>
|
||||
/// 权限授权处理器
|
||||
/// </summary>
|
||||
public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证方案提供对象
|
||||
/// </summary>
|
||||
public IAuthenticationSchemeProvider Schemes { get; set; }
|
||||
|
||||
private readonly IRoleModulePermissionServices _roleModulePermissionServices;
|
||||
private readonly IHttpContextAccessor _accessor;
|
||||
private readonly ISysUserInfoServices _userServices;
|
||||
private readonly IUser _user;
|
||||
private readonly IRoleModulePermissionServices _roleModulePermissionServices;
|
||||
private readonly IHttpContextAccessor _accessor;
|
||||
private readonly ISysUserInfoServices _userServices;
|
||||
private readonly IUser _user;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数注入
|
||||
/// </summary>
|
||||
/// <param name="schemes"></param>
|
||||
/// <param name="roleModulePermissionServices"></param>
|
||||
/// <param name="accessor"></param>
|
||||
/// <param name="userServices"></param>
|
||||
/// <param name="user"></param>
|
||||
public PermissionHandler(IAuthenticationSchemeProvider schemes, IRoleModulePermissionServices roleModulePermissionServices, IHttpContextAccessor accessor, ISysUserInfoServices userServices, IUser user)
|
||||
{
|
||||
_accessor = accessor;
|
||||
_userServices = userServices;
|
||||
_user = user;
|
||||
Schemes = schemes;
|
||||
_roleModulePermissionServices = roleModulePermissionServices;
|
||||
}
|
||||
/// <summary>
|
||||
/// 构造函数注入
|
||||
/// </summary>
|
||||
/// <param name="schemes"></param>
|
||||
/// <param name="roleModulePermissionServices"></param>
|
||||
/// <param name="accessor"></param>
|
||||
/// <param name="userServices"></param>
|
||||
/// <param name="user"></param>
|
||||
public PermissionHandler(IAuthenticationSchemeProvider schemes,
|
||||
IRoleModulePermissionServices roleModulePermissionServices, IHttpContextAccessor accessor,
|
||||
ISysUserInfoServices userServices, IUser user)
|
||||
{
|
||||
_accessor = accessor;
|
||||
_userServices = userServices;
|
||||
_user = user;
|
||||
Schemes = schemes;
|
||||
_roleModulePermissionServices = roleModulePermissionServices;
|
||||
}
|
||||
|
||||
// 重写异步处理程序
|
||||
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
|
||||
{
|
||||
var httpContext = _accessor.HttpContext;
|
||||
// 重写异步处理程序
|
||||
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
|
||||
PermissionRequirement requirement)
|
||||
{
|
||||
var httpContext = _accessor.HttpContext;
|
||||
|
||||
// 获取系统中所有的角色和菜单的关系集合
|
||||
if (!requirement.Permissions.Any())
|
||||
{
|
||||
var data = await _roleModulePermissionServices.RoleModuleMaps();
|
||||
var list = new List<PermissionItem>();
|
||||
// ids4和jwt切换
|
||||
// ids4
|
||||
if (Permissions.IsUseIds4)
|
||||
{
|
||||
list = (from item in data
|
||||
where item.IsDeleted == false
|
||||
orderby item.Id
|
||||
select new PermissionItem
|
||||
{
|
||||
Url = item.Module?.LinkUrl,
|
||||
Role = item.Role?.Id.ObjToString(),
|
||||
}).ToList();
|
||||
}
|
||||
// jwt
|
||||
else
|
||||
{
|
||||
list = (from item in data
|
||||
where item.IsDeleted == false
|
||||
orderby item.Id
|
||||
select new PermissionItem
|
||||
{
|
||||
Url = item.Module?.LinkUrl,
|
||||
Role = item.Role?.Name.ObjToString(),
|
||||
}).ToList();
|
||||
}
|
||||
// 获取系统中所有的角色和菜单的关系集合
|
||||
if (!requirement.Permissions.Any())
|
||||
{
|
||||
var data = await _roleModulePermissionServices.RoleModuleMaps();
|
||||
var list = new List<PermissionItem>();
|
||||
// ids4和jwt切换
|
||||
// ids4
|
||||
if (Permissions.IsUseIds4)
|
||||
{
|
||||
list = (from item in data
|
||||
where item.IsDeleted == false
|
||||
orderby item.Id
|
||||
select new PermissionItem
|
||||
{
|
||||
Url = item.Module?.LinkUrl,
|
||||
Role = item.Role?.Id.ObjToString(),
|
||||
}).ToList();
|
||||
}
|
||||
// jwt
|
||||
else
|
||||
{
|
||||
list = (from item in data
|
||||
where item.IsDeleted == false
|
||||
orderby item.Id
|
||||
select new PermissionItem
|
||||
{
|
||||
Url = item.Module?.LinkUrl,
|
||||
Role = item.Role?.Name.ObjToString(),
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
requirement.Permissions = list;
|
||||
}
|
||||
requirement.Permissions = list;
|
||||
}
|
||||
|
||||
if (httpContext != null)
|
||||
{
|
||||
var questUrl = httpContext.Request.Path.Value.ToLower();
|
||||
if (httpContext != null)
|
||||
{
|
||||
var questUrl = httpContext.Request.Path.Value.ToLower();
|
||||
|
||||
// 整体结构类似认证中间件UseAuthentication的逻辑,具体查看开源地址
|
||||
// https://github.com/dotnet/aspnetcore/blob/master/src/Security/Authentication/Core/src/AuthenticationMiddleware.cs
|
||||
httpContext.Features.Set<IAuthenticationFeature>(new AuthenticationFeature
|
||||
{
|
||||
OriginalPath = httpContext.Request.Path,
|
||||
OriginalPathBase = httpContext.Request.PathBase
|
||||
});
|
||||
// 整体结构类似认证中间件UseAuthentication的逻辑,具体查看开源地址
|
||||
// https://github.com/dotnet/aspnetcore/blob/master/src/Security/Authentication/Core/src/AuthenticationMiddleware.cs
|
||||
httpContext.Features.Set<IAuthenticationFeature>(new AuthenticationFeature
|
||||
{
|
||||
OriginalPath = httpContext.Request.Path,
|
||||
OriginalPathBase = httpContext.Request.PathBase
|
||||
});
|
||||
|
||||
// Give any IAuthenticationRequestHandler schemes a chance to handle the request
|
||||
// 主要作用是: 判断当前是否需要进行远程验证,如果是就进行远程验证
|
||||
var handlers = httpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
|
||||
foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
|
||||
{
|
||||
if (await handlers.GetHandlerAsync(httpContext, scheme.Name) is IAuthenticationRequestHandler handler && await handler.HandleRequestAsync())
|
||||
{
|
||||
context.Fail();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Give any IAuthenticationRequestHandler schemes a chance to handle the request
|
||||
// 主要作用是: 判断当前是否需要进行远程验证,如果是就进行远程验证
|
||||
var handlers = httpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
|
||||
foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
|
||||
{
|
||||
if (await handlers.GetHandlerAsync(httpContext, scheme.Name) is IAuthenticationRequestHandler
|
||||
handler && await handler.HandleRequestAsync())
|
||||
{
|
||||
context.Fail();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//判断请求是否拥有凭据,即有没有登录
|
||||
var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
|
||||
if (defaultAuthenticate != null)
|
||||
{
|
||||
var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name);
|
||||
|
||||
// 是否开启测试环境
|
||||
var isTestCurrent = AppSettings.app(new string[] {"AppSettings", "UseLoadTest"}).ObjToBool();
|
||||
|
||||
//判断请求是否拥有凭据,即有没有登录
|
||||
var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
|
||||
if (defaultAuthenticate != null)
|
||||
{
|
||||
var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name);
|
||||
//result?.Principal不为空即登录成功
|
||||
if (result?.Principal != null || isTestCurrent)
|
||||
{
|
||||
if (!isTestCurrent) httpContext.User = result.Principal;
|
||||
|
||||
// 是否开启测试环境
|
||||
var isTestCurrent = AppSettings.app(new string[] { "AppSettings", "UseLoadTest" }).ObjToBool();
|
||||
// 获取当前用户的角色信息
|
||||
var currentUserRoles = new List<string>();
|
||||
// ids4和jwt切换
|
||||
// ids4
|
||||
if (Permissions.IsUseIds4)
|
||||
{
|
||||
currentUserRoles = (from item in httpContext.User.Claims
|
||||
where item.Type == "role"
|
||||
select item.Value).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
// jwt
|
||||
currentUserRoles = (from item in httpContext.User.Claims
|
||||
where item.Type == requirement.ClaimType
|
||||
select item.Value).ToList();
|
||||
}
|
||||
|
||||
//result?.Principal不为空即登录成功
|
||||
if (result?.Principal != null || isTestCurrent)
|
||||
{
|
||||
if (!isTestCurrent) httpContext.User = result.Principal;
|
||||
//超级管理员 默认拥有所有权限
|
||||
if (currentUserRoles.All(s => s != "SuperAdmin"))
|
||||
{
|
||||
var isMatchRole = false;
|
||||
var permisssionRoles = requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role));
|
||||
foreach (var item in permisssionRoles)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Regex.Match(questUrl, item.Url?.ObjToString().ToLower())?.Value == questUrl)
|
||||
{
|
||||
isMatchRole = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前用户的角色信息
|
||||
var currentUserRoles = new List<string>();
|
||||
// ids4和jwt切换
|
||||
// ids4
|
||||
if (Permissions.IsUseIds4)
|
||||
{
|
||||
currentUserRoles = (from item in httpContext.User.Claims
|
||||
where item.Type == "role"
|
||||
select item.Value).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
// jwt
|
||||
currentUserRoles = (from item in httpContext.User.Claims
|
||||
where item.Type == requirement.ClaimType
|
||||
select item.Value).ToList();
|
||||
}
|
||||
//验证权限
|
||||
if (currentUserRoles.Count <= 0 || !isMatchRole)
|
||||
{
|
||||
context.Fail();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 判断token是否过期,过期则重新登录
|
||||
var isExp = false;
|
||||
// ids4和jwt切换
|
||||
// ids4
|
||||
if (Permissions.IsUseIds4)
|
||||
{
|
||||
isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == "exp")?.Value) != null &&
|
||||
DateHelper.StampToDateTime(httpContext.User.Claims
|
||||
.SingleOrDefault(s => s.Type == "exp")?.Value) >= DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
// jwt
|
||||
isExp =
|
||||
(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)
|
||||
?.Value) != null &&
|
||||
DateTime.Parse(httpContext.User.Claims
|
||||
.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now;
|
||||
}
|
||||
|
||||
var isMatchRole = false;
|
||||
var permisssionRoles = requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role));
|
||||
foreach (var item in permisssionRoles)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Regex.Match(questUrl, item.Url?.ObjToString().ToLower())?.Value == questUrl)
|
||||
{
|
||||
isMatchRole = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
if (!isExp)
|
||||
{
|
||||
context.Fail(new AuthorizationFailureReason(this, "授权已过期,请重新授权"));
|
||||
return;
|
||||
}
|
||||
|
||||
//验证权限
|
||||
if (currentUserRoles.Count <= 0 || !isMatchRole)
|
||||
{
|
||||
context.Fail();
|
||||
return;
|
||||
}
|
||||
//校验签发时间
|
||||
if (!Permissions.IsUseIds4)
|
||||
{
|
||||
var value = httpContext.User.Claims
|
||||
.SingleOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value;
|
||||
if (value != null)
|
||||
{
|
||||
var user = await _userServices.QueryById(_user.ID, true);
|
||||
if (user.CriticalModifyTime > value.ObjToDate())
|
||||
{
|
||||
_user.MessageModel = new ApiResponse(StatusCode.CODE401, "很抱歉,授权已失效,请重新授权")
|
||||
.MessageModel;
|
||||
context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.msg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断token是否过期,过期则重新登录
|
||||
var isExp = false;
|
||||
// ids4和jwt切换
|
||||
// ids4
|
||||
if (Permissions.IsUseIds4)
|
||||
{
|
||||
isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == "exp")?.Value) != null && DateHelper.StampToDateTime(httpContext.User.Claims.SingleOrDefault(s => s.Type == "exp")?.Value) >= DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
// jwt
|
||||
isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) != null && DateTime.Parse(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now;
|
||||
}
|
||||
context.Succeed(requirement);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isExp)
|
||||
{
|
||||
context.Fail(new AuthorizationFailureReason(this, "授权已过期,请重新授权"));
|
||||
return;
|
||||
}
|
||||
//判断没有登录时,是否访问登录的url,并且是Post请求,并且是form表单提交类型,否则为失败
|
||||
if (!(questUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) &&
|
||||
(!httpContext.Request.Method.Equals("POST") || !httpContext.Request.HasFormContentType)))
|
||||
{
|
||||
context.Fail();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//校验签发时间
|
||||
if (!Permissions.IsUseIds4)
|
||||
{
|
||||
var value = httpContext.User.Claims.SingleOrDefault(s => s.Type == JwtRegisteredClaimNames.Iat)?.Value;
|
||||
if (value != null)
|
||||
{
|
||||
var user = await _userServices.QueryById(_user.ID, true);
|
||||
if (user.CriticalModifyTime > value.ObjToDate())
|
||||
{
|
||||
_user.MessageModel = new ApiResponse(StatusCode.CODE401, "很抱歉,授权已失效,请重新授权").MessageModel;
|
||||
context.Fail(new AuthorizationFailureReason(this, _user.MessageModel.msg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.Succeed(requirement);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//判断没有登录时,是否访问登录的url,并且是Post请求,并且是form表单提交类型,否则为失败
|
||||
if (!(questUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST") || !httpContext.Request.HasFormContentType)))
|
||||
{
|
||||
context.Fail();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//context.Succeed(requirement);
|
||||
}
|
||||
}
|
||||
//context.Succeed(requirement);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,126 +13,130 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Blog.Core.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// SqlSugar 启动服务
|
||||
/// </summary>
|
||||
public static class SqlsugarSetup
|
||||
{
|
||||
private static readonly MemoryCache Cache = new MemoryCache(new MemoryCacheOptions());
|
||||
/// <summary>
|
||||
/// SqlSugar 启动服务
|
||||
/// </summary>
|
||||
public static class SqlsugarSetup
|
||||
{
|
||||
private static readonly MemoryCache Cache = new MemoryCache(new MemoryCacheOptions());
|
||||
|
||||
public static void AddSqlsugarSetup(this IServiceCollection services)
|
||||
{
|
||||
if (services == null) throw new ArgumentNullException(nameof(services));
|
||||
public static void AddSqlsugarSetup(this IServiceCollection services)
|
||||
{
|
||||
if (services == null) throw new ArgumentNullException(nameof(services));
|
||||
|
||||
// 默认添加主数据库连接
|
||||
MainDb.CurrentDbConnId = AppSettings.app(new string[] { "MainDB" });
|
||||
// 默认添加主数据库连接
|
||||
MainDb.CurrentDbConnId = AppSettings.app(new string[] {"MainDB"});
|
||||
|
||||
// SqlSugarScope是线程安全,可使用单例注入
|
||||
// 参考:https://www.donet5.com/Home/Doc?typeId=1181
|
||||
services.AddSingleton<ISqlSugarClient>(o =>
|
||||
{
|
||||
var memoryCache = o.GetRequiredService<IMemoryCache>();
|
||||
BaseDBConfig.MutiConnectionString.slaveDbs.ForEach(s =>
|
||||
{
|
||||
BaseDBConfig.AllSlaveConfigs.Add(new SlaveConnectionConfig()
|
||||
{
|
||||
HitRate = s.HitRate,
|
||||
ConnectionString = s.Connection
|
||||
});
|
||||
});
|
||||
|
||||
// 从库
|
||||
var listConfig_Slave = new List<SlaveConnectionConfig>();
|
||||
BaseDBConfig.MutiConnectionString.slaveDbs.ForEach(s =>
|
||||
{
|
||||
listConfig_Slave.Add(new SlaveConnectionConfig()
|
||||
{
|
||||
HitRate = s.HitRate,
|
||||
ConnectionString = s.Connection
|
||||
});
|
||||
});
|
||||
BaseDBConfig.MutiConnectionString.allDbs.ForEach(m =>
|
||||
{
|
||||
var config = new ConnectionConfig()
|
||||
{
|
||||
ConfigId = m.ConnId.ObjToString().ToLower(),
|
||||
ConnectionString = m.Connection,
|
||||
DbType = (DbType) m.DbType,
|
||||
IsAutoCloseConnection = true,
|
||||
// Check out more information: https://github.com/anjoy8/Blog.Core/issues/122
|
||||
//IsShardSameThread = false,
|
||||
MoreSettings = new ConnMoreSettings()
|
||||
{
|
||||
//IsWithNoLockQuery = true,
|
||||
IsAutoRemoveDataCache = true,
|
||||
SqlServerCodeFirstNvarchar = true,
|
||||
},
|
||||
// 从库
|
||||
SlaveConnectionConfigs = BaseDBConfig.AllSlaveConfigs,
|
||||
// 自定义特性
|
||||
ConfigureExternalServices = new ConfigureExternalServices()
|
||||
{
|
||||
EntityService = (property, column) =>
|
||||
{
|
||||
if (column.IsPrimarykey && property.PropertyType == typeof(int))
|
||||
{
|
||||
column.IsIdentity = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
InitKeyType = InitKeyType.Attribute
|
||||
};
|
||||
if (SqlSugarConst.LogConfigId.ToLower().Equals(m.ConnId.ToLower()))
|
||||
{
|
||||
BaseDBConfig.LogConfig = config;
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseDBConfig.ValidConfig.Add(config);
|
||||
}
|
||||
|
||||
BaseDBConfig.MutiConnectionString.allDbs.ForEach(m =>
|
||||
{
|
||||
var config = new ConnectionConfig()
|
||||
{
|
||||
ConfigId = m.ConnId.ObjToString().ToLower(),
|
||||
ConnectionString = m.Connection,
|
||||
DbType = (DbType)m.DbType,
|
||||
IsAutoCloseConnection = true,
|
||||
// Check out more information: https://github.com/anjoy8/Blog.Core/issues/122
|
||||
//IsShardSameThread = false,
|
||||
MoreSettings = new ConnMoreSettings()
|
||||
{
|
||||
//IsWithNoLockQuery = true,
|
||||
IsAutoRemoveDataCache = true,
|
||||
SqlServerCodeFirstNvarchar = true,
|
||||
},
|
||||
// 从库
|
||||
SlaveConnectionConfigs = listConfig_Slave,
|
||||
// 自定义特性
|
||||
ConfigureExternalServices = new ConfigureExternalServices()
|
||||
{
|
||||
DataInfoCacheService = new SqlSugarMemoryCacheService(memoryCache),
|
||||
EntityService = (property, column) =>
|
||||
{
|
||||
if (column.IsPrimarykey && property.PropertyType == typeof(int))
|
||||
{
|
||||
column.IsIdentity = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
InitKeyType = InitKeyType.Attribute
|
||||
};
|
||||
if (SqlSugarConst.LogConfigId.ToLower().Equals(m.ConnId.ToLower()))
|
||||
{
|
||||
BaseDBConfig.LogConfig = config;
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseDBConfig.ValidConfig.Add(config);
|
||||
}
|
||||
BaseDBConfig.AllConfigs.Add(config);
|
||||
});
|
||||
|
||||
BaseDBConfig.AllConfig.Add(config);
|
||||
});
|
||||
if (BaseDBConfig.LogConfig is null)
|
||||
{
|
||||
throw new ApplicationException("未配置Log库连接");
|
||||
}
|
||||
|
||||
if (BaseDBConfig.LogConfig is null)
|
||||
{
|
||||
throw new ApplicationException("未配置Log库连接");
|
||||
}
|
||||
|
||||
return new SqlSugarScope(BaseDBConfig.AllConfig, db =>
|
||||
{
|
||||
BaseDBConfig.ValidConfig.ForEach(config =>
|
||||
{
|
||||
var dbProvider = db.GetConnectionScope((string)config.ConfigId);
|
||||
// SqlSugarScope是线程安全,可使用单例注入
|
||||
// 参考:https://www.donet5.com/Home/Doc?typeId=1181
|
||||
services.AddSingleton<ISqlSugarClient>(o =>
|
||||
{
|
||||
var memoryCache = o.GetRequiredService<IMemoryCache>();
|
||||
|
||||
// 打印SQL语句
|
||||
dbProvider.Aop.OnLogExecuting = (s, parameters) => SqlSugarAop.OnLogExecuting(dbProvider, s, parameters, config);
|
||||
foreach (var config in BaseDBConfig.AllConfigs)
|
||||
{
|
||||
config.ConfigureExternalServices.DataInfoCacheService = new SqlSugarMemoryCacheService(memoryCache);
|
||||
}
|
||||
|
||||
// 数据审计
|
||||
dbProvider.Aop.DataExecuting = SqlSugarAop.DataExecuting;
|
||||
return new SqlSugarScope(BaseDBConfig.AllConfigs, db =>
|
||||
{
|
||||
BaseDBConfig.ValidConfig.ForEach(config =>
|
||||
{
|
||||
var dbProvider = db.GetConnectionScope((string) config.ConfigId);
|
||||
|
||||
// 配置实体假删除过滤器
|
||||
RepositorySetting.SetDeletedEntityFilter(dbProvider);
|
||||
// 配置实体数据权限
|
||||
RepositorySetting.SetTenantEntityFilter(dbProvider);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
// 打印SQL语句
|
||||
dbProvider.Aop.OnLogExecuting = (s, parameters) =>
|
||||
SqlSugarAop.OnLogExecuting(dbProvider, s, parameters, config);
|
||||
|
||||
private static string GetWholeSql(SugarParameter[] paramArr, string sql)
|
||||
{
|
||||
foreach (var param in paramArr)
|
||||
{
|
||||
sql.Replace(param.ParameterName, param.Value.ObjToString());
|
||||
}
|
||||
// 数据审计
|
||||
dbProvider.Aop.DataExecuting = SqlSugarAop.DataExecuting;
|
||||
|
||||
return sql;
|
||||
}
|
||||
// 配置实体假删除过滤器
|
||||
RepositorySetting.SetDeletedEntityFilter(dbProvider);
|
||||
// 配置实体数据权限
|
||||
RepositorySetting.SetTenantEntityFilter(dbProvider);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static string GetParas(SugarParameter[] pars)
|
||||
{
|
||||
string key = "【SQL参数】:";
|
||||
foreach (var param in pars)
|
||||
{
|
||||
key += $"{param.ParameterName}:{param.Value}\n";
|
||||
}
|
||||
private static string GetWholeSql(SugarParameter[] paramArr, string sql)
|
||||
{
|
||||
foreach (var param in paramArr)
|
||||
{
|
||||
sql.Replace(param.ParameterName, param.Value.ObjToString());
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
private static string GetParas(SugarParameter[] pars)
|
||||
{
|
||||
string key = "【SQL参数】:";
|
||||
foreach (var param in pars)
|
||||
{
|
||||
key += $"{param.ParameterName}:{param.Value}\n";
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
10
Blog.Core.Model/Systems/DataBase/DataBaseReadType.cs
Normal file
10
Blog.Core.Model/Systems/DataBase/DataBaseReadType.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace Blog.Core.Model.Systems.DataBase;
|
||||
|
||||
/// <summary>
|
||||
/// 数据库读取类型
|
||||
/// </summary>
|
||||
public enum DataBaseReadType
|
||||
{
|
||||
Db,
|
||||
Entity
|
||||
}
|
10
Blog.Core.Model/Systems/DataBase/DatabaseOutput.cs
Normal file
10
Blog.Core.Model/Systems/DataBase/DatabaseOutput.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using SqlSugar;
|
||||
|
||||
namespace Blog.Core.Model.Systems.DataBase;
|
||||
|
||||
public class DatabaseOutput
|
||||
{
|
||||
public string ConfigId { get; set; }
|
||||
|
||||
public DbType DbType { get; set; }
|
||||
}
|
36
Blog.Core.Model/Systems/DataBase/DbColumnInfoOutput.cs
Normal file
36
Blog.Core.Model/Systems/DataBase/DbColumnInfoOutput.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
namespace Blog.Core.Model.Systems.DataBase;
|
||||
|
||||
public class DbColumnInfoOutput
|
||||
{
|
||||
public string TableName { get; set; }
|
||||
|
||||
public int TableId { get; set; }
|
||||
|
||||
public string DbColumnName { get; set; }
|
||||
|
||||
public string PropertyName { get; set; }
|
||||
|
||||
public string DataType { get; set; }
|
||||
|
||||
public int Length { get; set; }
|
||||
|
||||
public string ColumnDescription { get; set; }
|
||||
|
||||
public string DefaultValue { get; set; }
|
||||
|
||||
public bool IsNullable { get; set; }
|
||||
|
||||
public bool IsIdentity { get; set; }
|
||||
|
||||
public bool IsPrimarykey { get; set; }
|
||||
|
||||
public object Value { get; set; }
|
||||
|
||||
public int DecimalDigits { get; set; }
|
||||
|
||||
public int Scale { get; set; }
|
||||
|
||||
public bool IsArray { get; set; }
|
||||
|
||||
internal bool IsJson { get; set; }
|
||||
}
|
9
Blog.Core.Model/Systems/DataBase/EditColumnInput.cs
Normal file
9
Blog.Core.Model/Systems/DataBase/EditColumnInput.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace Blog.Core.Model.Systems.DataBase;
|
||||
|
||||
public class EditColumnInput
|
||||
{
|
||||
public string ConfigId { get; set; }
|
||||
public string TableName { get; set; }
|
||||
public string DbColumnName { get; set; }
|
||||
public string ColumnDescription { get; set; }
|
||||
}
|
10
Blog.Core.Model/Systems/DataBase/EditTableInput.cs
Normal file
10
Blog.Core.Model/Systems/DataBase/EditTableInput.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace Blog.Core.Model.Systems.DataBase;
|
||||
|
||||
public class EditTableInput
|
||||
{
|
||||
public string ConfigId { get; set; }
|
||||
|
||||
public string TableName { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
}
|
Loading…
Reference in New Issue
Block a user