Merge branch 'dev' of https://git.tuotong-tech.com/tnb/tnb.server into dev
This commit is contained in:
@@ -87,6 +87,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tnb.Extend.Entitys", "exten
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tnb.Extend.Interfaces", "extend\Tnb.Extend.Interfaces\Tnb.Extend.Interfaces.csproj", "{2E9F8B23-37B9-42BD-A62F-140A38C43A89}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tnb.SqlSugar", "common\Tnb.SqlSugar\Tnb.SqlSugar.csproj", "{E600E59F-18EE-4DBC-8298-BEF4307F69D9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -209,6 +211,10 @@ Global
|
||||
{2E9F8B23-37B9-42BD-A62F-140A38C43A89}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2E9F8B23-37B9-42BD-A62F-140A38C43A89}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2E9F8B23-37B9-42BD-A62F-140A38C43A89}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E600E59F-18EE-4DBC-8298-BEF4307F69D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E600E59F-18EE-4DBC-8298-BEF4307F69D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E600E59F-18EE-4DBC-8298-BEF4307F69D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E600E59F-18EE-4DBC-8298-BEF4307F69D9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -242,6 +248,7 @@ Global
|
||||
{0282541C-4295-4A2A-A826-54E9C69718D9} = {A5AB62A9-B65A-4348-BC4A-60EF67FC1B9D}
|
||||
{08A36D02-DC53-4895-9E1C-E02BC1BBA890} = {A5AB62A9-B65A-4348-BC4A-60EF67FC1B9D}
|
||||
{2E9F8B23-37B9-42BD-A62F-140A38C43A89} = {A5AB62A9-B65A-4348-BC4A-60EF67FC1B9D}
|
||||
{E600E59F-18EE-4DBC-8298-BEF4307F69D9} = {E4872924-2348-4E06-881A-08625ED98E9F}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {646DDD1C-F143-42C2-894F-F5C7B3A0CE74}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"Cache": {
|
||||
"CacheType": "RedisCache", //MemoryCache
|
||||
"ip": "localhost",
|
||||
"port": 9204,
|
||||
"port": 6379,
|
||||
"password": "05jWEoJa8v",
|
||||
"RedisConnectionString": "{0}:{1},password={2}, poolsize=500,ssl=false,defaultDatabase=6"
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ public class UserManager : IUserManager, IScoped
|
||||
UserAgent userAgent = new UserAgent(_httpContext);
|
||||
var data = new UserInfoModel();
|
||||
var ipAddress = NetHelper.Ip;
|
||||
var ipAddressName = await NetHelper.GetLocation(ipAddress);
|
||||
//var ipAddressName = await NetHelper.GetLocation(ipAddress);
|
||||
var userDataScope = await GetUserDataScopeAsync(UserId);
|
||||
var sysConfigInfo = await _repository.AsSugarClient().Queryable<SysConfigEntity>().FirstAsync(s => s.Category.Equals("SysConfig") && s.Key.ToLower().Equals("tokentimeout"));
|
||||
data = await _repository.AsQueryable().Where(it => it.Id == UserId)
|
||||
@@ -251,8 +251,8 @@ public class UserManager : IUserManager, IScoped
|
||||
data.loginTime = DateTime.Now;
|
||||
data.prevLogin = (await _repository.AsSugarClient().Queryable<SysConfigEntity>().FirstAsync(x => x.Category.Equals("SysConfig") && x.Key.ToLower().Equals("lastlogintimeswitch"))).Value.ParseToInt();
|
||||
data.loginIPAddress = ipAddress;
|
||||
data.loginIPAddressName = ipAddressName;
|
||||
data.prevLoginIPAddressName = await NetHelper.GetLocation(data.prevLoginIPAddress);
|
||||
//data.loginIPAddressName = ipAddressName;
|
||||
//data.prevLoginIPAddressName = await NetHelper.GetLocation(data.prevLoginIPAddress);
|
||||
data.loginPlatForm = userAgent.RawValue;
|
||||
data.subsidiary = await GetSubsidiaryAsync(data.organizeId, data.isAdministrator);
|
||||
data.subordinates = await this.GetSubordinatesAsync(UserId);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<ProjectReference Include="..\..\message\Tnb.Message.Entitys\Tnb.Message.Entitys.csproj" />
|
||||
<ProjectReference Include="..\..\system\Tnb.Systems.Entitys\Tnb.Systems.Entitys.csproj" />
|
||||
<ProjectReference Include="..\..\visualdev\Tnb.VisualDev.Entitys\Tnb.VisualDev.Entitys.csproj" />
|
||||
|
||||
<ProjectReference Include="..\Tnb.WebSockets\Tnb.WebSockets.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Tnb.SqlSugar" Version="2023.3.24.1010" />
|
||||
<!--<ProjectReference Include="..\..\..\Tnb.Core\src\Tnb.SqlSugar\Tnb.SqlSugar.csproj" />-->
|
||||
<ProjectReference Include="..\Tnb.SqlSugar\Tnb.SqlSugar.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--<ItemGroup>
|
||||
|
||||
37
common/Tnb.SqlSugar/Extensions/JsonSqlExtFunc.cs
Normal file
37
common/Tnb.SqlSugar/Extensions/JsonSqlExtFunc.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using SqlSugar;
|
||||
|
||||
namespace JNPF.Extras.DatabaseAccessor.SqlSugar.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Newtonsoft.Json 序列化拓展.
|
||||
/// </summary>
|
||||
public static class JsonSqlExtFunc
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static List<SqlFuncExternal> ExpMethods = new List<SqlFuncExternal>
|
||||
{
|
||||
new SqlFuncExternal(){
|
||||
UniqueMethodName = "ToObject",
|
||||
MethodValue = (expInfo, dbType, expContext) =>
|
||||
{
|
||||
//var value = string.Empty;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotSupportedException"></exception>
|
||||
public static T ToObject<T>(string value)
|
||||
{
|
||||
//这里不能写任何实现代码,需要在上面的配置中实现
|
||||
throw new NotSupportedException("Can only be used in expressions");
|
||||
}
|
||||
}
|
||||
84
common/Tnb.SqlSugar/Extensions/PagedQueryableExtensions.cs
Normal file
84
common/Tnb.SqlSugar/Extensions/PagedQueryableExtensions.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace SqlSugar;
|
||||
|
||||
/// <summary>
|
||||
/// 分页拓展类
|
||||
/// </summary>
|
||||
public static class PagedQueryableExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 分页拓展
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <returns></returns>
|
||||
public static SqlSugarPagedList<TEntity> ToPagedList<TEntity>(this ISugarQueryable<TEntity> entity, int pageIndex, int pageSize)
|
||||
where TEntity : new()
|
||||
{
|
||||
var totalCount = 0;
|
||||
var items = entity.ToPageList(pageIndex, pageSize, ref totalCount);
|
||||
var pagination = new Pagination()
|
||||
{
|
||||
CurrentPage = pageIndex,
|
||||
PageSize = pageSize,
|
||||
Total = (int)totalCount
|
||||
};
|
||||
return new SqlSugarPagedList<TEntity>
|
||||
{
|
||||
pagination = pagination,
|
||||
list = items
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页拓展
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<SqlSugarPagedList<TEntity>> ToPagedListAsync<TEntity>(this ISugarQueryable<TEntity> entity, int pageIndex, int pageSize)
|
||||
where TEntity : new()
|
||||
{
|
||||
RefAsync<int> totalCount = 0;
|
||||
var items = await entity.ToPageListAsync(pageIndex, pageSize, totalCount);
|
||||
var pagination = new Pagination()
|
||||
{
|
||||
CurrentPage = pageIndex,
|
||||
PageSize = pageSize,
|
||||
Total = (int)totalCount
|
||||
};
|
||||
return new SqlSugarPagedList<TEntity>
|
||||
{
|
||||
pagination = pagination,
|
||||
list = items
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页拓展
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<SqlSugarPagedList<TEntity>> ToPagedListAsync<T, TEntity>(this ISugarQueryable<T> entity, int pageIndex, int pageSize, Expression<Func<T, TEntity>> expression)
|
||||
{
|
||||
RefAsync<int> totalCount = 0;
|
||||
var items = await entity.ToPageListAsync(pageIndex, pageSize, totalCount, expression);
|
||||
var pagination = new Pagination()
|
||||
{
|
||||
CurrentPage = pageIndex,
|
||||
PageSize = pageSize,
|
||||
Total = (int)totalCount
|
||||
};
|
||||
return new SqlSugarPagedList<TEntity>
|
||||
{
|
||||
pagination = pagination,
|
||||
list = items
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using SqlSugar;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// SqlSugar 拓展类
|
||||
/// </summary>
|
||||
public static class SqlSugarServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加 SqlSugar 拓展
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="config"></param>
|
||||
/// <param name="buildAction"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddSqlSugar(this IServiceCollection services, ConnectionConfig config, Action<ISqlSugarClient> buildAction = default)
|
||||
{
|
||||
var list = new List<ConnectionConfig>();
|
||||
list.Add(config);
|
||||
return services.AddSqlSugar(list, buildAction);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加 SqlSugar 拓展
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configs"></param>
|
||||
/// <param name="buildAction"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddSqlSugar(this IServiceCollection services, List<ConnectionConfig> configs, Action<ISqlSugarClient> buildAction = default)
|
||||
{
|
||||
// SqlSugarScope是线程安全,可使用单例注入
|
||||
// 注册 SqlSugar 客户端
|
||||
services.AddSingleton<ISqlSugarClient>(u =>
|
||||
{
|
||||
var sqlSugarClient = new SqlSugarScope(configs);
|
||||
buildAction?.Invoke(sqlSugarClient);
|
||||
|
||||
return sqlSugarClient;
|
||||
});
|
||||
|
||||
// 注册 SqlSugar 仓储
|
||||
services.AddScoped(typeof(ISqlSugarRepository<>), typeof(SqlSugarRepository<>));
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
225
common/Tnb.SqlSugar/Extensions/TenantLinkExtensions.cs
Normal file
225
common/Tnb.SqlSugar/Extensions/TenantLinkExtensions.cs
Normal file
@@ -0,0 +1,225 @@
|
||||
using JNPF.DataEncryption;
|
||||
using JNPF.Extras.DatabaseAccessor.SqlSugar;
|
||||
using JNPF.Extras.DatabaseAccessor.SqlSugar.Extensions;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Configuration.Json;
|
||||
|
||||
namespace SqlSugar;
|
||||
|
||||
/// <summary>
|
||||
/// JNPF多租户拓展.
|
||||
/// </summary>
|
||||
public class JNPFTenantExtensions
|
||||
{
|
||||
//public static IConfiguration _config { get; set; }
|
||||
private static ConnectionStringsOptions _connOpt { get; }
|
||||
|
||||
public static string skey = "Vl4WTqna9aZCgswjieIP";
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数.
|
||||
/// </summary>
|
||||
static JNPFTenantExtensions()
|
||||
{
|
||||
var config = new ConfigurationBuilder().AddJsonFile("Configurations/ConnectionStrings.json", true, true).Build();
|
||||
_connOpt = config.GetSection("ConnectionStrings").Get<ConnectionStringsOptions>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取普通链接.
|
||||
/// </summary>
|
||||
/// <param name="configId">配置ID.</param>
|
||||
/// <param name="tableName">数据库名称.</param>
|
||||
/// <returns></returns>
|
||||
public static ConnectionConfigOptions GetLinkToOrdinary(string configId, string tableName)
|
||||
{
|
||||
List<DBConnectionConfig> configList = new List<DBConnectionConfig>();
|
||||
var connStr = string.Format(_connOpt.DefaultConnection, _connOpt.Host, _connOpt.Port, _connOpt.DBName, _connOpt.UserName, _connOpt.Password);
|
||||
configList.Add(new DBConnectionConfig()
|
||||
{
|
||||
IsMaster = true,
|
||||
ServiceName = tableName,
|
||||
dbType = ToDbType(_connOpt.DBType),
|
||||
connectionStr = DESCEncryption.Encrypt(connStr, skey)
|
||||
});
|
||||
return new ConnectionConfigOptions()
|
||||
{
|
||||
ConfigId = configId,
|
||||
IsCustom = false,
|
||||
IsMasterSlaveSeparation = false,
|
||||
ConfigList = configList
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取自定义链接
|
||||
/// </summary>
|
||||
/// <param name="configId">配置ID.</param>
|
||||
/// <param name="tenantLinkModels">数据库连接列表.</param>
|
||||
/// <returns></returns>
|
||||
public static ConnectionConfigOptions GetLinkToCustom(string configId, List<TenantLinkModel> tenantLinkModels)
|
||||
{
|
||||
List<DBConnectionConfig> configList = new List<DBConnectionConfig>();
|
||||
foreach (var item in tenantLinkModels)
|
||||
{
|
||||
if (item.configType == 0)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item.connectionStr))
|
||||
{
|
||||
configList.Add(new DBConnectionConfig()
|
||||
{
|
||||
IsMaster = true,
|
||||
dbType = ToDbType(item.dbType),
|
||||
ServiceName = item.serviceName,
|
||||
connectionStr = item.connectionStr,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
configList.Add(new DBConnectionConfig()
|
||||
{
|
||||
IsMaster = true,
|
||||
dbType = ToDbType(item.dbType),
|
||||
connectionStr = DESCEncryption.Encrypt(ToConnectionString(ToDbType(item.dbType), item.host, Convert.ToInt32(item.port), item.serviceName, item.userName, item.password, item.dbSchema), skey)
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item.connectionStr))
|
||||
{
|
||||
configList.Add(new DBConnectionConfig()
|
||||
{
|
||||
IsMaster = false,
|
||||
dbType = ToDbType(item.dbType),
|
||||
ServiceName = item.serviceName,
|
||||
connectionStr = item.connectionStr,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
configList.Add(new DBConnectionConfig()
|
||||
{
|
||||
IsMaster = false,
|
||||
dbType = ToDbType(item.dbType),
|
||||
connectionStr = DESCEncryption.Encrypt(ToConnectionString(ToDbType(item.dbType), item.host, Convert.ToInt32(item.port), item.serviceName, item.userName, item.password, item.dbSchema), skey)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return new ConnectionConfigOptions()
|
||||
{
|
||||
ConfigId = configId,
|
||||
IsCustom = true,
|
||||
IsMasterSlaveSeparation = tenantLinkModels.Any(it => it.configType.Equals(1)),
|
||||
ConfigList = configList
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取配置.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static ConnectionConfig GetConfig(ConnectionConfigOptions options)
|
||||
{
|
||||
if (!options.IsCustom)
|
||||
{
|
||||
DBConnectionConfig config = options.ConfigList.FirstOrDefault();
|
||||
return new ConnectionConfig()
|
||||
{
|
||||
DbType = config.dbType,
|
||||
ConfigId = options.ConfigId,
|
||||
IsAutoCloseConnection = true,
|
||||
ConnectionString = DESCEncryption.Decrypt(config.connectionStr, skey),
|
||||
ConfigureExternalServices = new ConfigureExternalServices()
|
||||
{
|
||||
SqlFuncServices = JsonSqlExtFunc.ExpMethods
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var slaveConnection = new List<SlaveConnectionConfig>();
|
||||
foreach (var item in options.ConfigList.FindAll(it => it.IsMaster.Equals(false)))
|
||||
{
|
||||
slaveConnection.Add(new SlaveConnectionConfig()
|
||||
{
|
||||
HitRate = 10,
|
||||
ConnectionString = DESCEncryption.Decrypt(item.connectionStr, skey)
|
||||
});
|
||||
}
|
||||
return new ConnectionConfig()
|
||||
{
|
||||
DbType = options.ConfigList.Find(it => it.IsMaster.Equals(true)).dbType,
|
||||
ConfigId = options.ConfigId,
|
||||
IsAutoCloseConnection = true,
|
||||
ConnectionString = DESCEncryption.Decrypt(options.ConfigList.Find(it => it.IsMaster.Equals(true)).connectionStr, skey),
|
||||
SlaveConnectionConfigs = slaveConnection,
|
||||
ConfigureExternalServices = new ConfigureExternalServices()
|
||||
{
|
||||
SqlFuncServices = JsonSqlExtFunc.ExpMethods
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换数据库类型.
|
||||
/// </summary>
|
||||
/// <param name="dbType">数据库类型.</param>
|
||||
/// <returns></returns>
|
||||
public static DbType ToDbType(string dbType)
|
||||
{
|
||||
switch (dbType.ToLower())
|
||||
{
|
||||
case "mysql":
|
||||
return SqlSugar.DbType.MySql;
|
||||
case "oracle":
|
||||
return SqlSugar.DbType.Oracle;
|
||||
case "dm8":
|
||||
case "dm":
|
||||
return SqlSugar.DbType.Dm;
|
||||
case "kdbndp":
|
||||
case "kingbasees":
|
||||
return SqlSugar.DbType.Kdbndp;
|
||||
case "postgresql":
|
||||
return SqlSugar.DbType.PostgreSQL;
|
||||
default:
|
||||
return SqlSugar.DbType.SqlServer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换连接字符串.
|
||||
/// </summary>
|
||||
/// <param name="dbType">数据库类型.</param>
|
||||
/// <param name="host">主机地址.</param>
|
||||
/// <param name="port">端口.</param>
|
||||
/// <param name="tableName">数据库名.</param>
|
||||
/// <param name="userName">用户名.</param>
|
||||
/// <param name="password">密码.</param>
|
||||
/// <param name="dbSchema">模式.</param>
|
||||
/// <returns></returns>
|
||||
public static string ToConnectionString(DbType dbType, string host, int port, string tableName, string userName, string password, string dbSchema)
|
||||
{
|
||||
switch (dbType)
|
||||
{
|
||||
case DbType.SqlServer:
|
||||
return string.Format("Data Source={0},{1};Initial Catalog={2};User ID={3};Password={4};Connection Timeout=5;MultipleActiveResultSets=true", host, port, tableName, userName, password);
|
||||
case DbType.Oracle:
|
||||
return string.Format("Data Source={0}:{1}/{2};User ID={3};Password={4};", host, port, dbSchema, userName, password);
|
||||
case DbType.MySql:
|
||||
return string.Format("server={0};port={1};database={2};user={3};password={4};AllowLoadLocalInfile=true", host, port, tableName, userName, password);
|
||||
case DbType.Dm:
|
||||
return string.Format("server={0};port={1};database={2};User Id={3};PWD={4}", host, port, tableName, userName, password);
|
||||
case DbType.Kdbndp:
|
||||
return string.Format("server={0};port={1};database={2};UID={3};PWD={4}", host, port, tableName, userName, password);
|
||||
case DbType.PostgreSQL:
|
||||
return string.Format("server={0};port={1};Database={2};User Id={3};Password={4}", host, port, tableName, userName, password);
|
||||
default:
|
||||
return string.Format("Data Source={0},{4};Initial Catalog={1};User ID={2};Password={3};Connection Timeout=5;MultipleActiveResultSets=true", host, tableName, userName, password, port);
|
||||
}
|
||||
}
|
||||
}
|
||||
45
common/Tnb.SqlSugar/Internal/SqlSugarPagedList.cs
Normal file
45
common/Tnb.SqlSugar/Internal/SqlSugarPagedList.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
namespace SqlSugar;
|
||||
|
||||
/// <summary>
|
||||
/// 分页信息
|
||||
/// </summary>
|
||||
public class Pagination
|
||||
{
|
||||
/// <summary>
|
||||
/// 页码
|
||||
/// </summary>
|
||||
public int CurrentPage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 页容量
|
||||
/// </summary>
|
||||
public int PageSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 总条数
|
||||
/// </summary>
|
||||
public int Total { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页泛型集合
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public class SqlSugarPagedList<TEntity>
|
||||
{
|
||||
/// <summary>
|
||||
/// 分页数据
|
||||
/// </summary>
|
||||
public Pagination pagination { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前页集合
|
||||
/// </summary>
|
||||
public IEnumerable<TEntity> list { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页集合
|
||||
/// </summary>
|
||||
public class PagedModel : SqlSugarPagedList<object>
|
||||
{}
|
||||
87
common/Tnb.SqlSugar/Models/TenantLinkModel.cs
Normal file
87
common/Tnb.SqlSugar/Models/TenantLinkModel.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
namespace SqlSugar;
|
||||
|
||||
/// <summary>
|
||||
/// 租户数据库连接模型.
|
||||
/// </summary>
|
||||
public class TenantLinkModel
|
||||
{
|
||||
/// <summary>
|
||||
/// id.
|
||||
/// </summary>
|
||||
public string id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据库名.
|
||||
/// </summary>
|
||||
public string serviceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户名.
|
||||
/// </summary>
|
||||
public string userName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态(1-可用,0-禁用).
|
||||
/// </summary>
|
||||
public int enabledMark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 端口.
|
||||
/// </summary>
|
||||
public string port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接名称.
|
||||
/// </summary>
|
||||
public string fullName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主机地址.
|
||||
/// </summary>
|
||||
public string host { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码.
|
||||
/// </summary>
|
||||
public string password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序.
|
||||
/// </summary>
|
||||
public long? sortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模式.
|
||||
/// </summary>
|
||||
public string dbSchema { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表空间.
|
||||
/// </summary>
|
||||
public string tableSpace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接配置(0:主,1:从).
|
||||
/// </summary>
|
||||
public int? configType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据库类型.
|
||||
/// </summary>
|
||||
public string dbType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Oracle参数字段.
|
||||
/// </summary>
|
||||
public string oracleParam { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义连接语句.
|
||||
/// </summary>
|
||||
public string connectionStr { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 租户id.
|
||||
/// </summary>
|
||||
public string tenantId { get; set; }
|
||||
}
|
||||
53
common/Tnb.SqlSugar/Options/ConnectionConfigOptions.cs
Normal file
53
common/Tnb.SqlSugar/Options/ConnectionConfigOptions.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
namespace SqlSugar;
|
||||
|
||||
/// <summary>
|
||||
/// 数据库连接字符串配置选项.
|
||||
/// </summary>
|
||||
public class ConnectionConfigOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置ID.
|
||||
/// </summary>
|
||||
public string ConfigId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否自定义配置.
|
||||
/// </summary>
|
||||
public bool IsCustom { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否主从分离.
|
||||
/// </summary>
|
||||
public bool IsMasterSlaveSeparation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 配置列表.
|
||||
/// </summary>
|
||||
public List<DBConnectionConfig> ConfigList { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据库连接字符串配置.
|
||||
/// </summary>
|
||||
public class DBConnectionConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否主库.
|
||||
/// </summary>
|
||||
public bool IsMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据库名.
|
||||
/// </summary>
|
||||
public string ServiceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据库类型.
|
||||
/// </summary>
|
||||
public DbType dbType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义连接语句.
|
||||
/// </summary>
|
||||
public string connectionStr { get; set; }
|
||||
}
|
||||
49
common/Tnb.SqlSugar/Options/ConnectionStringsOptions.cs
Normal file
49
common/Tnb.SqlSugar/Options/ConnectionStringsOptions.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using JNPF.ConfigurableOptions;
|
||||
|
||||
namespace SqlSugar;
|
||||
|
||||
/// <summary>
|
||||
/// 数据库配置.
|
||||
/// </summary>
|
||||
public sealed class ConnectionStringsOptions : IConfigurableOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认数据库编号.
|
||||
/// </summary>
|
||||
public string ConfigId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据库类型.
|
||||
/// </summary>
|
||||
public string DBType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据库名称.
|
||||
/// </summary>
|
||||
public string DBName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据库地址.
|
||||
/// </summary>
|
||||
public string Host { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据库端口号.
|
||||
/// </summary>
|
||||
public int Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账号.
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码.
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认数据库连接字符串.
|
||||
/// </summary>
|
||||
public string DefaultConnection { get; set; }
|
||||
}
|
||||
19
common/Tnb.SqlSugar/Options/TenantOptions.cs
Normal file
19
common/Tnb.SqlSugar/Options/TenantOptions.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using JNPF.ConfigurableOptions;
|
||||
|
||||
namespace SqlSugar;
|
||||
|
||||
/// <summary>
|
||||
/// 租户配置.
|
||||
/// </summary>
|
||||
public sealed class TenantOptions : IConfigurableOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否多租户模式.
|
||||
/// </summary>
|
||||
public bool MultiTenancy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 多租户数据接口.
|
||||
/// </summary>
|
||||
public string MultiTenancyDBInterFace { get; set; }
|
||||
}
|
||||
12
common/Tnb.SqlSugar/Repositories/ISqlSugarRepository.cs
Normal file
12
common/Tnb.SqlSugar/Repositories/ISqlSugarRepository.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace SqlSugar;
|
||||
|
||||
/// <summary>
|
||||
/// SqlSugar 仓储接口定义
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public partial interface ISqlSugarRepository<TEntity> : ISimpleClient<TEntity>
|
||||
where TEntity : class, new()
|
||||
{
|
||||
}
|
||||
111
common/Tnb.SqlSugar/Repositories/SqlSugarRepository.cs
Normal file
111
common/Tnb.SqlSugar/Repositories/SqlSugarRepository.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using JNPF;
|
||||
using JNPF.DataEncryption;
|
||||
using JNPF.FriendlyException;
|
||||
using JNPF.JsonSerialization;
|
||||
using JNPF.Logging;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SqlSugar;
|
||||
|
||||
/// <summary>
|
||||
/// SqlSugar 仓储实现类
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public partial class SqlSugarRepository<TEntity> : SimpleClient<TEntity>, ISqlSugarRepository<TEntity>
|
||||
where TEntity : class, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public SqlSugarRepository(ISqlSugarClient context = null) : base(context)
|
||||
{
|
||||
// 获取数据库连接选项
|
||||
ConnectionStringsOptions connectionStrings = App.GetConfig<ConnectionStringsOptions>("ConnectionStrings", true);
|
||||
|
||||
// 获取多租户选项
|
||||
TenantOptions tenant = App.GetConfig<TenantOptions>("Tenant", true);
|
||||
var httpContext = App.HttpContext;
|
||||
|
||||
base.Context = (SqlSugarScope)context;
|
||||
|
||||
string tenantId = connectionStrings.ConfigId;
|
||||
|
||||
if (httpContext?.GetEndpoint()?.Metadata?.GetMetadata<AllowAnonymousAttribute>() == null || !string.IsNullOrEmpty(httpContext?.Request.Query["token"]))
|
||||
{
|
||||
if (tenant.MultiTenancy && httpContext != null)
|
||||
{
|
||||
var connectionConfig = new ConnectionConfigOptions();
|
||||
if (httpContext.Request.Headers.ContainsKey("Authorization"))
|
||||
{
|
||||
connectionConfig = JSON.Deserialize<ConnectionConfigOptions>(httpContext?.User.FindFirst("ConnectionConfig")?.Value);
|
||||
tenantId = connectionConfig.ConfigId;
|
||||
}
|
||||
else if (!httpContext.Request.Headers.ContainsKey("Authorization"))
|
||||
{
|
||||
var token = Regex.Match(httpContext.Request.QueryString.Value, @"[?&]token=Bearer%20([\w\.-]+)($|&)").Groups[1].Value;
|
||||
var claims = JWTEncryption.ReadJwtToken(token.Replace("Bearer ", "").Replace("bearer ", ""))?.Claims;
|
||||
connectionConfig = JSON.Deserialize<ConnectionConfigOptions>(claims.FirstOrDefault(e => e.Type == "ConnectionConfig").Value);
|
||||
tenantId = connectionConfig.ConfigId;
|
||||
}
|
||||
|
||||
if (!base.Context.AsTenant().IsAnyConnection(connectionConfig.ConfigId))
|
||||
{
|
||||
base.Context.AsTenant().AddConnection(JNPFTenantExtensions.GetConfig(connectionConfig));
|
||||
}
|
||||
base.Context = base.Context.AsTenant().GetConnectionScope(connectionConfig.ConfigId);
|
||||
|
||||
if (!base.Context.Ado.IsValidConnection())
|
||||
{
|
||||
throw Oops.Oh("数据库连接错误");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
base.Context = base.Context.AsTenant().GetConnectionScope(tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置超时时间
|
||||
base.Context.Ado.CommandTimeOut = 30;
|
||||
base.Context.Aop.OnLogExecuted = (sql, pars) =>
|
||||
{
|
||||
// 在控制台输出sql语句
|
||||
var oldColor = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
var finalSql = UtilMethods.GetSqlString(Context.CurrentConnectionConfig.DbType, sql, pars);
|
||||
Console.WriteLine($"【{DateTime.Now.ToString("HH:mm:ss.fff")}——SQL执行完成】{Context.Ado.SqlExecutionTime.TotalMilliseconds} ms");
|
||||
Console.WriteLine(finalSql);
|
||||
Console.ForegroundColor = oldColor;
|
||||
if (Context.Ado.SqlExecutionTime.TotalMilliseconds > 3000)
|
||||
{
|
||||
Log.Warning($"慢查询: {Context.Ado.SqlExecutionTime.TotalMilliseconds}ms, SQL: " + finalSql);
|
||||
}
|
||||
Console.WriteLine();
|
||||
//App.PrintToMiniProfiler("SqlSugar", "Info", sql + "\r\n" + base.Context.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
|
||||
};
|
||||
base.Context.Aop.OnError = (ex) =>
|
||||
{
|
||||
Log.Error(UtilMethods.GetSqlString(base.Context.CurrentConnectionConfig.DbType, ex.Sql, (SugarParameter[])ex.Parametres));
|
||||
//App.PrintToMiniProfiler("SqlSugar", "Error", $"{ex.Message}{Environment.NewLine}{ex.Sql}{pars}{Environment.NewLine}");
|
||||
};
|
||||
|
||||
if (base.Context.CurrentConnectionConfig.DbType == DbType.Oracle)
|
||||
{
|
||||
base.Context.Aop.OnExecutingChangeSql = (sql, pars) =>
|
||||
{
|
||||
if (pars != null)
|
||||
{
|
||||
foreach (var item in pars)
|
||||
{
|
||||
//如果是DbTppe=string设置成OracleDbType.Nvarchar2
|
||||
item.IsNvarchar2 = true;
|
||||
}
|
||||
};
|
||||
return new KeyValuePair<string, SugarParameter[]>(sql, pars);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
25
common/Tnb.SqlSugar/Tnb.SqlSugar.csproj
Normal file
25
common/Tnb.SqlSugar/Tnb.SqlSugar.csproj
Normal file
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="$(SolutionDir)\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<!--<VersionSuffix>$([System.DateTime]::Now.Year).$([System.DateTime]::Now.Month).$([System.DateTime]::Now.Day).$([System.DateTime]::Now.ToString(HHmm))</VersionSuffix>
|
||||
<AssemblyVersion>$(VersionSuffix)</AssemblyVersion>
|
||||
<Version>$(VersionSuffix)</Version>-->
|
||||
<Authors>ToTong</Authors>
|
||||
<Description>TNB 数据库访问器 SqlSugar 插件</Description>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<NoWarn>$(NoWarn);CS1591;</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.60" />
|
||||
<PackageReference Include="Tnb.Core" Version="2023.3.24.1010" />
|
||||
<!--<ProjectReference Include="..\..\..\Tnb.Core\Tnb.Core.csproj" />-->
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -10,6 +10,7 @@ using JNPF.Logging.Attributes;
|
||||
using JNPF.Systems.Entitys.Permission;
|
||||
using JNPF.TaskScheduler;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Cors;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
|
||||
@@ -22,20 +23,21 @@ namespace JNPF.Systems.Common;
|
||||
[Route("api")]
|
||||
public class TestService : IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly ISqlSugarRepository<UserEntity> _sqlSugarRepository;
|
||||
private readonly ISqlSugarRepository<UserEntity> _repository;
|
||||
private readonly SqlSugarScope _sugar;
|
||||
private readonly IDataBaseManager _databaseService;
|
||||
private readonly ITenant _db;
|
||||
|
||||
public TestService(ISqlSugarRepository<UserEntity> sqlSugarRepository, ISqlSugarClient context, IDataBaseManager databaseService)
|
||||
public TestService(ISqlSugarRepository<UserEntity> repository, IDataBaseManager databaseService)
|
||||
{
|
||||
_sqlSugarRepository = sqlSugarRepository;
|
||||
_repository = repository;
|
||||
_sugar = (SqlSugarScope)repository.AsSugarClient();
|
||||
_databaseService = databaseService;
|
||||
_db = context.AsTenant();
|
||||
}
|
||||
|
||||
[HttpGet("test")]
|
||||
[AllowAnonymous]
|
||||
[IgnoreLog]
|
||||
[DisableCors]
|
||||
public async Task<dynamic> test()
|
||||
{
|
||||
try
|
||||
@@ -44,7 +46,7 @@ public class TestService : IDynamicApiController, ITransient
|
||||
//var xx = App.HttpContext.Request.Host.ToString();
|
||||
//var sql = "SELECT TOP 1 [F_PARENTID],[F_PROCESSID],[F_ENCODE],[F_FULLNAME],[F_FLOWURGENT],[F_FLOWID],[F_FLOWCODE],[F_FLOWNAME],[F_FLOWTYPE],[F_FLOWCATEGORY],[F_FLOWFORM],[F_FLOWFORMCONTENTJSON],[F_FLOWTEMPLATEJSON],[F_FLOWVERSION],[F_STARTTIME],[F_ENDTIME],[F_THISSTEP],[F_THISSTEPID],[F_GRADE],[F_STATUS],[F_COMPLETION],[F_DESCRIPTION],[F_SORTCODE],[F_ISASYNC],[F_ISBATCH],[F_TASKNODEID],[F_TEMPLATEID],[F_REJECTDATAID],[F_DELEGATEUSER],[F_CREATORTIME],[F_CREATORUSERID],[F_ENABLEDMARK],[F_LastModifyTime],[F_LastModifyUserId],[F_DeleteMark],[F_DeleteTime],[F_DeleteUserId],[F_Id] FROM [FLOW_TASK] WHERE (( [F_DeleteMark] IS NULL ) AND ( [F_Id] = N'367536153122855173' ))";
|
||||
//var darta = _sqlSugarRepository.AsSugarClient().Ado.SqlQuery<dynamic>(sql);
|
||||
var data = _sqlSugarRepository.GetFirst(a => true);
|
||||
var data = await _repository.GetFirstAsync(a => true);
|
||||
var json = App.GetService<IJsonSerializerProvider>();
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
<ProjectReference Include="..\..\common\Tnb.CollectiveOAuth\Tnb.CollectiveOAuth.csproj" />
|
||||
<ProjectReference Include="..\..\message\Tnb.Message.Interfaces\Tnb.Message.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\..\visualdev\Tnb.VisualDev.Engine\Tnb.VisualDev.Engine.csproj" />
|
||||
<ProjectReference Include="..\Tnb.Systems.Interfaces\Tnb.Systems.Interfaces.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -12,10 +12,7 @@
|
||||
<ProjectReference Include="..\..\common\Tnb.Common.Core\Tnb.Common.Core.csproj" />
|
||||
<ProjectReference Include="..\..\extend\Tnb.Extend.Interfaces\Tnb.Extend.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\..\message\Tnb.Message.Interfaces\Tnb.Message.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\..\system\Tnb.Systems.Interfaces\Tnb.Systems.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\..\workflow\Tnb.WorkFlow.Interfaces\Tnb.WorkFlow.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\Tnb.VisualDev.Engine\Tnb.VisualDev.Engine.csproj" />
|
||||
<ProjectReference Include="..\Tnb.VisualDev.Interfaces\Tnb.VisualDev.Interfaces.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
<ProjectReference Include="..\..\common\Tnb.Common\Tnb.Common.csproj" />
|
||||
<ProjectReference Include="..\..\visualdev\Tnb.VisualDev.Engine\Tnb.VisualDev.Engine.csproj" />
|
||||
<ProjectReference Include="..\..\visualdev\Tnb.VisualDev\Tnb.VisualDev.csproj" />
|
||||
<ProjectReference Include="..\Tnb.WorkFlow.Interfaces\Tnb.WorkFlow.Interfaces.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user