Ver Fonte

优化调整多库租户模式

zuohuaijun há 3 anos atrás
pai
commit
8d4bbb7588

+ 5 - 3
Admin.NET/Admin.NET.Application/AppConfig.json

@@ -2,8 +2,8 @@
     "$schema": "https://gitee.com/dotnetchina/Furion/raw/net6/schemas/v3/furion-schema.json",
 
     "DbConnection": {
+        // ConnectionConfig具体配置见SqlSugar
         "ConnectionConfigs": [
-            // 默认第一个为主库
             {
                 "ConfigId": "default",
                 "DbType": "Sqlite", // MySql、SqlServer、Sqlite、Oracle、PostgreSQL、Dm、Kdbndp、Oscar、MySqlConnector、Access
@@ -11,12 +11,11 @@
                 "EnableInitDb": true, // 启用库表初始化
                 "EnableDiffLog": false // 启用库表差异日志
             },
-            // 其他业务库
             {
                 "ConfigId": "test",
                 "DbType": "Sqlite",
                 "ConnectionString": "DataSource=./Test.db",
-                "EnableInitDb": false, // 启用库表初始化
+                "EnableInitDb": true, // 启用库表初始化
                 "EnableDiffLog": false // 启用库表差异日志
             }
         ]
@@ -27,6 +26,7 @@
         "FrontRootPath": "Vben2", //前端文件根目录
         "BackendApplicationNamespace": "Admin.NET.Application" //后端生成到的项目
     },
+    // 微信相关
     "Wechat": {
         // 公众号
         "WechatAppId": "",
@@ -39,6 +39,7 @@
         "WxOpenToken": "",
         "WxOpenEncodingAESKey": ""
     },
+    // 微信支付
     "WechatPay": {
         "AppId": "", // 微信公众平台AppId、开放平台AppId、小程序AppId、企业微信CorpId
         "MerchantId": "", // 商户平台的商户号
@@ -46,6 +47,7 @@
         "MerchantCertificateSerialNumber": "", // 商户平台的证书序列号
         "MerchantCertificatePrivateKey": "\\WxPayCert\\apiclient_key.pem" // 商户平台的API证书私钥(apiclient_key.pem文件内容)
     },
+    // 支付回调
     "PayCallBack": {
         "WechatPayUrl": "/notify/weChatPay/unifiedorder", // 微信支付回调
         "WechatRefundUrl": "/notify/weChatPay/refund", // 微信退款回调

+ 9 - 9
Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj

@@ -25,24 +25,24 @@
   <ItemGroup>
     <PackageReference Include="AngleSharp" Version="0.17.1" />
     <PackageReference Include="AspNetCoreRateLimit" Version="4.0.2" />
-    <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.7.3" />
-    <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.7.3" />
-    <PackageReference Include="Furion.Pure" Version="4.7.3" />
+    <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.7.5" />
+    <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.7.5" />
+    <PackageReference Include="Furion.Pure" Version="4.7.5" />
     <PackageReference Include="Lazy.Captcha.Core" Version="1.1.6" />
-    <PackageReference Include="Magicodes.IE.Excel" Version="2.6.9" />
-    <PackageReference Include="Magicodes.IE.Pdf" Version="2.6.9" />
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.10" />
+    <PackageReference Include="Magicodes.IE.Excel" Version="2.7.0" />
+    <PackageReference Include="Magicodes.IE.Pdf" Version="2.7.0" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.11" />
     <PackageReference Include="NEST" Version="7.17.5" />
     <PackageReference Include="NETCore.MailKit" Version="2.1.0" />
     <PackageReference Include="NewLife.Redis" Version="5.0.2022.1101" />
     <PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.1.9" />
-    <PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="2.20.0" />
+    <PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="2.20.1" />
     <PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="2.13.1" />
     <PackageReference Include="SqlSugarCore" Version="5.1.3.30" />
-    <PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.21" />
+    <PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.22" />
     <PackageReference Include="UAParser" Version="3.1.47" />
     <PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
-    <PackageReference Include="Masuit.Tools.Core" Version="2.5.7.1" />
+    <PackageReference Include="Masuit.Tools.Core" Version="2.5.7.2" />
   </ItemGroup>
 
   <ItemGroup>

+ 36 - 5
Admin.NET/Admin.NET.Core/Admin.NET.Core.xml

@@ -1392,6 +1392,11 @@
             备注
             </summary>
         </member>
+        <member name="P:Admin.NET.Core.SysTenant.Status">
+            <summary>
+            状态
+            </summary>
+        </member>
         <member name="T:Admin.NET.Core.SysTimer">
             <summary>
             定时任务
@@ -2573,6 +2578,16 @@
             已有相同编码或名称
             </summary>
         </member>
+        <member name="F:Admin.NET.Core.ErrorCodeEnum.Z1001">
+            <summary>
+            默认租户状态禁止修改
+            </summary>
+        </member>
+        <member name="F:Admin.NET.Core.ErrorCodeEnum.Z1002">
+            <summary>
+            禁止创建此类型的数据库
+            </summary>
+        </member>
         <member name="T:Admin.NET.Core.GenderEnum">
             <summary>
             性别枚举
@@ -6045,6 +6060,11 @@
             </summary>
             <returns></returns>
         </member>
+        <member name="P:Admin.NET.Core.Service.TenantInput.Status">
+            <summary>
+            状态
+            </summary>
+        </member>
         <member name="P:Admin.NET.Core.Service.PageTenantInput.Name">
             <summary>
             名称
@@ -6090,6 +6110,13 @@
             <param name="input"></param>
             <returns></returns>
         </member>
+        <member name="M:Admin.NET.Core.Service.SysTenantService.SetTenantStatus(Admin.NET.Core.Service.TenantInput)">
+            <summary>
+            设置租户状态
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
         <member name="M:Admin.NET.Core.Service.SysTenantService.InitNewTenant(Admin.NET.Core.SysTenant)">
             <summary>
             新增租户初始化(Id隔离)
@@ -6849,22 +6876,26 @@
             </summary>
             <param name="config"></param>
         </member>
-        <member name="M:Admin.NET.Core.SqlSugarSetup.SetDbAop(SqlSugar.SqlSugarScopeProvider,Admin.NET.Core.DbConnectionConfig)">
+        <member name="M:Admin.NET.Core.SqlSugarSetup.SetDbAop(SqlSugar.SqlSugarScopeProvider)">
             <summary>
             配置Aop
             </summary>
             <param name="db"></param>
-            <param name="config"></param>
         </member>
-        <member name="M:Admin.NET.Core.SqlSugarSetup.InitDataBase(SqlSugar.SqlSugarScope,Admin.NET.Core.DbConnectionOptions)">
+        <member name="M:Admin.NET.Core.SqlSugarSetup.InitDataBase(SqlSugar.ITenant,Admin.NET.Core.DbConnectionConfig,System.Int64)">
             <summary>
             初始化数据库结构
             </summary>
+            <param name="db"></param>
+            <param name="config"></param>
+            <param name="tenantId"></param>
         </member>
-        <member name="M:Admin.NET.Core.SqlSugarSetup.CreateDataBase(SqlSugar.ISqlSugarClient,Admin.NET.Core.DbConnectionConfig,System.Int64)">
+        <member name="M:Admin.NET.Core.SqlSugarSetup.InitTenantDb(SqlSugar.ITenant,System.Int64)">
             <summary>
-            初始化数据库结构
+            增加租户库连接
             </summary>
+            <param name="iTenant"></param>
+            <param name="tenantId"></param>
         </member>
         <member name="M:Admin.NET.Core.SqlSugarSetup.SetDeletedEntityFilter(SqlSugar.SqlSugarScopeProvider)">
             <summary>

+ 6 - 0
Admin.NET/Admin.NET.Core/Entity/SysTenant.cs

@@ -79,4 +79,10 @@ public class SysTenant : EntityBase
     [SugarColumn(ColumnDescription = "备注", Length = 128)]
     [MaxLength(128)]
     public string Remark { get; set; }
+
+    /// <summary>
+    /// 状态
+    /// </summary>
+    [SugarColumn(ColumnDescription = "状态")]
+    public StatusEnum Status { get; set; } = StatusEnum.Enable;
 }

+ 12 - 0
Admin.NET/Admin.NET.Core/Enum/ErrorCodeEnum.cs

@@ -503,4 +503,16 @@ public enum ErrorCodeEnum
     /// </summary>
     [ErrorCodeItemMetadata("已有相同编码或名称")]
     R2002,
+
+    /// <summary>
+    /// 默认租户状态禁止修改
+    /// </summary>
+    [ErrorCodeItemMetadata("默认租户状态禁止修改")]
+    Z1001,
+
+    /// <summary>
+    /// 禁止创建此类型的数据库
+    /// </summary>
+    [ErrorCodeItemMetadata("禁止创建此类型的数据库")]
+    Z1002,
 }

+ 11 - 4
Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs

@@ -58,9 +58,6 @@ public class SysAuthService : IDynamicApiController, ITransient
     [SuppressMonitor]
     public async Task<LoginOutput> Login([Required] LoginInput input)
     {
-        // 记录当前租户
-        _userManager.TenantId = input.TenantId;
-
         // 判断验证码
         var captchaEnabled = await GetCaptchaFlag();
         if (captchaEnabled && !_captcha.Validate(input.CodeId.ToString(), input.Code))
@@ -69,7 +66,17 @@ public class SysAuthService : IDynamicApiController, ITransient
         var encryptPasswod = MD5Encryption.Encrypt(input.Password);
 
         // 判断用户名密码
-        var user = await _sysUserRep.GetFirstAsync(u => u.Account.Equals(input.Account) && u.Password.Equals(encryptPasswod));
+        Expression<Func<SysUser, bool>> sysUserExp = u => u.Account.Equals(input.Account) && u.Password.Equals(encryptPasswod);
+        SysUser user = null;
+        if (input.TenantId > 0)
+        {
+            var db = App.GetRequiredService<ISqlSugarClient>().AsTenant();
+            user = await SqlSugarSetup.InitTenantDb(db, input.TenantId).Queryable<SysUser>().FirstAsync(sysUserExp);
+        }
+        else
+        {
+            user = await _sysUserRep.GetFirstAsync(sysUserExp);
+        }
         _ = user ?? throw Oops.Oh(ErrorCodeEnum.D1000);
 
         // 账号是否被冻结

+ 4 - 0
Admin.NET/Admin.NET.Core/Service/Tenant/Dto/TenantInput.cs

@@ -2,6 +2,10 @@
 
 public class TenantInput : BaseIdInput
 {
+    /// <summary>
+    /// 状态
+    /// </summary>
+    public StatusEnum Status { get; set; }
 }
 
 public class PageTenantInput : BasePageInput

+ 29 - 7
Admin.NET/Admin.NET.Core/Service/Tenant/SysTenantService.cs

@@ -18,7 +18,6 @@ public class SysTenantService : IDynamicApiController, ITransient
     private readonly SysRoleMenuService _sysRoleMenuService;
     private readonly SysConfigService _sysConfigService;
     private readonly SysCacheService _sysCacheService;
-    private readonly ISqlSugarClient _db;
 
     public SysTenantService(SqlSugarRepository<SysTenant> tenantRep,
         SqlSugarRepository<SysOrg> orgRep,
@@ -31,8 +30,7 @@ public class SysTenantService : IDynamicApiController, ITransient
         SysUserRoleService sysUserRoleService,
         SysRoleMenuService sysRoleMenuService,
         SysConfigService sysConfigService,
-        SysCacheService sysCacheService,
-        ISqlSugarClient db)
+        SysCacheService sysCacheService)
     {
         _tenantRep = tenantRep;
         _orgRep = orgRep;
@@ -46,7 +44,6 @@ public class SysTenantService : IDynamicApiController, ITransient
         _sysRoleMenuService = sysRoleMenuService;
         _sysConfigService = sysConfigService;
         _sysCacheService = sysCacheService;
-        _db = db;
     }
 
     /// <summary>
@@ -70,7 +67,7 @@ public class SysTenantService : IDynamicApiController, ITransient
     [NonAction]
     public async Task<List<SysTenant>> GetTenantDbList()
     {
-        return await _tenantRep.GetListAsync(u => u.TenantType == TenantTypeEnum.Db);
+        return await _tenantRep.GetListAsync(u => u.TenantType == TenantTypeEnum.Db && u.Status == StatusEnum.Enable);
     }
 
     /// <summary>
@@ -93,6 +90,25 @@ public class SysTenantService : IDynamicApiController, ITransient
         await InitNewTenant(tenant);
     }
 
+    /// <summary>
+    /// 设置租户状态
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [HttpPost("/sysTenant/setStatus")]
+    public async Task<int> SetTenantStatus(TenantInput input)
+    {
+        var tenant = await _tenantRep.GetFirstAsync(u => u.Id == input.Id);
+        if (tenant.ConfigId == SqlSugarConst.ConfigId)
+            throw Oops.Oh(ErrorCodeEnum.Z1001);
+
+        if (!Enum.IsDefined(typeof(StatusEnum), input.Status))
+            throw Oops.Oh(ErrorCodeEnum.D3005);
+
+        tenant.Status = input.Status;
+        return await _tenantRep.AsUpdateable(tenant).UpdateColumns(u => new { u.Status }).ExecuteCommandAsync();
+    }
+
     /// <summary>
     /// 新增租户初始化(Id隔离)
     /// </summary>
@@ -316,6 +332,9 @@ public class SysTenantService : IDynamicApiController, ITransient
         var tenant = await _tenantRep.GetFirstAsync(u => u.Id == input.Id);
         if (tenant == null) return;
 
+        if (tenant.DbType == SqlSugar.DbType.Oracle)
+            throw Oops.Oh(ErrorCodeEnum.Z1002);
+
         var dbConnection = new DbConnectionConfig
         {
             EnableInitDb = true,
@@ -324,7 +343,10 @@ public class SysTenantService : IDynamicApiController, ITransient
             ConnectionString = tenant.Connection,
             IsAutoCloseConnection = true,
         };
-
-        SqlSugarSetup.CreateDataBase(_db, dbConnection, tenant.Id);
+        SqlSugarSetup.SetDbConfig(dbConnection);
+        var db = App.GetRequiredService<ISqlSugarClient>();
+        db.AsTenant().AddConnection(dbConnection);
+        db.DbMaintenance.CreateDatabase();
+        SqlSugarSetup.InitDataBase(db.AsTenant(), dbConnection, tenant.Id);
     }
 }

+ 1 - 12
Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarRepository.cs

@@ -16,18 +16,7 @@ public class SqlSugarRepository<T> : SimpleClient<T> where T : class, new()
         var tenantId = App.GetRequiredService<UserManager>().TenantId;
         if (tenantId > 1)
         {
-            var tenant = App.GetRequiredService<SysCacheService>().Get<List<SysTenant>>(CacheConst.KeyTenant).FirstOrDefault(u => u.Id == tenantId);
-            if (!iTenant.IsAnyConnection(tenant.ConfigId))
-            {
-                iTenant.AddConnection(new ConnectionConfig()
-                {
-                    ConfigId = tenant.ConfigId,
-                    ConnectionString = tenant.Connection,
-                    DbType = tenant.DbType,
-                    IsAutoCloseConnection = true
-                });
-            }
-            base.Context = iTenant.GetConnectionScope(tenant.ConfigId);
+            base.Context = SqlSugarSetup.InitTenantDb(iTenant, tenantId);
         }
         else
         {

+ 49 - 92
Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarSetup.cs

@@ -1,5 +1,3 @@
-using Masuit.Tools;
-
 namespace Admin.NET.Core;
 
 public static class SqlSugarSetup
@@ -16,21 +14,25 @@ public static class SqlSugarSetup
             SetDbConfig(config);
         });
 
-        SqlSugarScope sqlSugar = new(dbOptions.ConnectionConfigs.Adapt<List<ConnectionConfig>>(), client =>
+        SqlSugarScope sqlSugar = new(dbOptions.ConnectionConfigs.Adapt<List<ConnectionConfig>>(), db =>
         {
             dbOptions.ConnectionConfigs.ForEach(config =>
             {
-                var db = client.GetConnectionScope((string)config.ConfigId);
-                SetDbAop(db, config);
+                SetDbAop(db.GetConnectionScope(config.ConfigId));
             });
         });
 
         // 初始化数据库表结构及种子数据
-        InitDataBase(sqlSugar, dbOptions);
+        dbOptions.ConnectionConfigs.ForEach(config =>
+        {
+            if (config.EnableInitDb && config.DbType != SqlSugar.DbType.Oracle)
+                sqlSugar.DbMaintenance.CreateDatabase();
+            InitDataBase(sqlSugar.AsTenant(), config);
+        });
 
         services.AddSingleton<ISqlSugarClient>(sqlSugar); // 单例注册
         services.AddScoped(typeof(SqlSugarRepository<>)); // 仓储注册
-        services.AddUnitOfWork<SqlSugarUnitOfWork>(); // 注册事务与工作单元
+        services.AddUnitOfWork<SqlSugarUnitOfWork>(); // 事务与工作单元注册
     }
 
     /// <summary>
@@ -62,9 +64,10 @@ public static class SqlSugarSetup
     /// 配置Aop
     /// </summary>
     /// <param name="db"></param>
-    /// <param name="config"></param>
-    public static void SetDbAop(this SqlSugarScopeProvider db, DbConnectionConfig config)
+    public static void SetDbAop(SqlSugarScopeProvider db)
     {
+        var config = db.CurrentConnectionConfig;
+
         // 设置超时时间
         db.Ado.CommandTimeOut = 30;
 
@@ -165,27 +168,23 @@ public static class SqlSugarSetup
     /// <summary>
     /// 初始化数据库结构
     /// </summary>
-    private static void InitDataBase(SqlSugarScope db, DbConnectionOptions dbOptions)
+    /// <param name="db"></param>
+    /// <param name="config"></param>
+    /// <param name="tenantId"></param>
+    public static void InitDataBase(ITenant db, DbConnectionConfig config, long tenantId = 0)
     {
-        // 创建数据库
-        dbOptions.ConnectionConfigs.ForEach(config =>
-        {
-            if (!config.EnableInitDb || config.DbType == SqlSugar.DbType.Oracle) return;
-            db.GetConnectionScope(config.ConfigId).DbMaintenance.CreateDatabase();
-        });
-
         // 获取所有实体表-初始化表结构
         var entityTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
             && u.IsDefined(typeof(SugarTable), false) && !u.IsDefined(typeof(NotTableAttribute), false));
         if (!entityTypes.Any()) return;
+        var db2 = db.GetConnectionScope(config.ConfigId);
         foreach (var entityType in entityTypes)
         {
-            var tAtt = entityType.GetCustomAttribute<TenantAttribute>(); // 多数据库
-            var configId = tAtt == null ? SqlSugarConst.ConfigId : tAtt.configId.ToString();
-            if (!dbOptions.ConnectionConfigs.FirstOrDefault(u => u.ConfigId == configId).EnableInitDb)
-                continue;
-            var db2 = db.GetConnectionScope(configId);
-            var splitTable = entityType.GetCustomAttribute<SplitTableAttribute>(); // 分表
+            var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
+            if (tAtt != null && tAtt.configId.ToString() != config.ConfigId) continue;
+            if (tAtt == null && config.ConfigId != SqlSugarConst.ConfigId && tenantId < 1) continue;
+
+            var splitTable = entityType.GetCustomAttribute<SplitTableAttribute>();
             if (splitTable == null)
                 db2.CodeFirst.InitTables(entityType);
             else
@@ -206,19 +205,24 @@ public static class SqlSugarSetup
 
             var entityType = seedType.GetInterfaces().First().GetGenericArguments().First();
             var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
-            var configId = tAtt == null ? SqlSugarConst.ConfigId : tAtt.configId.ToString();
-            if (!dbOptions.ConnectionConfigs.FirstOrDefault(u => u.ConfigId == configId).EnableInitDb)
-                continue;
-            var db2 = db.GetConnectionScope(configId);
+            if (tAtt != null && tAtt.configId.ToString() != config.ConfigId) continue;
+            if (tAtt == null && config.ConfigId != SqlSugarConst.ConfigId && tenantId < 1) continue;
+
             var seedDataTable = seedData.ToList().ToDataTable();
-            seedDataTable.TableName = db.EntityMaintenance.GetEntityInfo(entityType).DbTableName;
+            seedDataTable.TableName = db2.EntityMaintenance.GetEntityInfo(entityType).DbTableName;
+            // 创建租户库时修改租户Id
+            if (tenantId > 1 && seedDataTable.Columns.Contains(SqlSugarConst.TenantId))
+            {
+                foreach (DataRow dr in seedDataTable.Rows)
+                    dr[SqlSugarConst.TenantId] = tenantId;
+            }
             if (seedDataTable.Columns.Contains(SqlSugarConst.PrimaryKey))
             {
                 var storage = db2.Storageable(seedDataTable).WhereColumns(SqlSugarConst.PrimaryKey).ToStorage();
                 storage.AsInsertable.ExecuteCommand();
                 storage.AsUpdateable.ExecuteCommand();
             }
-            else // 没有主键或者不是预定义的主键(没主键有重复的可能)
+            else // 没有主键或者不是预定义的主键(有重复的可能)
             {
                 var storage = db2.Storageable(seedDataTable).ToStorage();
                 storage.AsInsertable.ExecuteCommand();
@@ -227,72 +231,25 @@ public static class SqlSugarSetup
     }
 
     /// <summary>
-    /// 初始化数据库结构
+    /// 增加租户库连接
     /// </summary>
-    public static void CreateDataBase(ISqlSugarClient db, DbConnectionConfig config, long tenantId)
+    /// <param name="iTenant"></param>
+    /// <param name="tenantId"></param>
+    public static SqlSugarScopeProvider InitTenantDb(ITenant iTenant, long tenantId)
     {
-        SetDbConfig(config);
-
-        var itenant = db.AsTenant();
-        // 创建数据库
-        if (!config.EnableInitDb || config.DbType == SqlSugar.DbType.Oracle) return;
-        itenant.AddConnection(config);
-        var dbProvider = itenant.GetConnectionScope(config.ConfigId);
-        SetDbAop(dbProvider, config);
-        dbProvider.DbMaintenance.CreateDatabase();
-
-        // 获取所有实体表-初始化表结构
-        var entityTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
-            && u.IsDefined(typeof(SugarTable), false) && !u.IsDefined(typeof(NotTableAttribute), false));
-        if (!entityTypes.Any()) return;
-        foreach (var entityType in entityTypes)
-        {
-            var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
-            if (tAtt != null) continue;
-            var db2 = itenant.GetConnectionScope(config.ConfigId);
-            var splitTable = entityType.GetCustomAttribute<SplitTableAttribute>();
-            if (splitTable == null)
-                db2.CodeFirst.InitTables(entityType);
-            else
-                db2.CodeFirst.SplitTables().InitTables(entityType);
-        }
-
-        // 获取所有种子配置-初始化数据
-        var seedDataTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
-            && u.GetInterfaces().Any(i => i.HasImplementedRawGeneric(typeof(ISqlSugarEntitySeedData<>))));
-        if (!seedDataTypes.Any()) return;
-        foreach (var seedType in seedDataTypes)
+        var tenant = App.GetRequiredService<SysCacheService>().Get<List<SysTenant>>(CacheConst.KeyTenant).FirstOrDefault(u => u.Id == tenantId);
+        if (!iTenant.IsAnyConnection(tenantId.ToString()))
         {
-            var instance = Activator.CreateInstance(seedType);
-
-            var hasDataMethod = seedType.GetMethod("HasData");
-            var seedData = ((IEnumerable)hasDataMethod?.Invoke(instance, null))?.Cast<object>();
-            if (seedData == null) continue;
-
-            var entityType = seedType.GetInterfaces().First().GetGenericArguments().First();
-            var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
-            if (tAtt != null) continue;
-            var db2 = itenant.GetConnectionScope(config.ConfigId);
-            var seedDataTable = seedData.ToList().ToDataTable();
-            seedDataTable.TableName = db.EntityMaintenance.GetEntityInfo(entityType).DbTableName;
-            // 设置租户Id
-            if (seedDataTable.Columns.Contains(SqlSugarConst.TenantId))
-            {
-                foreach (DataRow dr in seedDataTable.Rows)                
-                    dr[SqlSugarConst.TenantId] = tenantId;                
-            }
-            if (seedDataTable.Columns.Contains(SqlSugarConst.PrimaryKey))
+            iTenant.AddConnection(new ConnectionConfig()
             {
-                var storage = db2.Storageable(seedDataTable).WhereColumns(SqlSugarConst.PrimaryKey).ToStorage();
-                storage.AsInsertable.ExecuteCommand();
-                storage.AsUpdateable.ExecuteCommand();
-            }
-            else // 没有主键或者不是预定义的主键(没主键有重复的可能)
-            {
-                var storage = db2.Storageable(seedDataTable).ToStorage();
-                storage.AsInsertable.ExecuteCommand();
-            }
+                ConfigId = tenantId.ToString(),
+                ConnectionString = tenant.Connection,
+                DbType = tenant.DbType,
+                IsAutoCloseConnection = true
+            });
+            SetDbAop(iTenant.GetConnectionScope(tenantId.ToString()));
         }
+        return iTenant.GetConnectionScope(tenantId.ToString());
     }
 
     /// <summary>
@@ -452,7 +409,7 @@ public static class SqlSugarSetup
                 var entityFilters = ((IList)entityFilterMethod?.Invoke(instance, null))?.Cast<object>();
                 if (entityFilters == null) continue;
 
-                entityFilters.ForEach(u =>
+                foreach (var u in entityFilters)
                 {
                     var tableFilterItem = (TableFilterItem<object>)u;
                     var entityType = tableFilterItem.GetType().GetProperty("type", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tableFilterItem, null) as Type;
@@ -464,7 +421,7 @@ public static class SqlSugarSetup
 
                     tableFilterItems.Add(tableFilterItem);
                     db.QueryFilter.Add(tableFilterItem);
-                });
+                }
             }
             db.DataCache.Add(cacheKey, tableFilterItems);
         }

+ 6 - 0
Web/src/views/system/tenant/index.vue

@@ -30,6 +30,12 @@
 						<el-tag v-else> 库隔离 </el-tag>
 					</template>
 				</el-table-column>
+				<el-table-column prop="status" label="状态" width="70" align="center" show-overflow-tooltip>
+					<template #default="scope">
+						<el-tag type="success" v-if="scope.row.status === 1">启用</el-tag>
+						<el-tag type="danger" v-else>禁用</el-tag>
+					</template>
+				</el-table-column>
 				<el-table-column prop="dbType" label="数据库类型" align="center" show-overflow-tooltip>
 					<template #default="scope">
 						<el-tag v-if="scope.row.dbType === 0"> MySql </el-tag>