Przeglądaj źródła

优化多租户隔离逻辑 https://gitee.com/zuohuaijun/Admin.NET/issues/I61SEA

zuohuaijun 3 lat temu
rodzic
commit
6d68242828

+ 0 - 8
Admin.NET/Admin.NET.Application/Configuration/Database.json

@@ -5,19 +5,11 @@
         // 具体配置见SqlSugar官网
         // 具体配置见SqlSugar官网
         "ConnectionConfigs": [
         "ConnectionConfigs": [
             {
             {
-                "ConfigId": "default",
                 "DbType": "Sqlite", // MySql、SqlServer、Sqlite、Oracle、PostgreSQL、Dm、Kdbndp、Oscar、MySqlConnector、Access
                 "DbType": "Sqlite", // MySql、SqlServer、Sqlite、Oracle、PostgreSQL、Dm、Kdbndp、Oscar、MySqlConnector、Access
                 "ConnectionString": "DataSource=./Admin.NET.db",
                 "ConnectionString": "DataSource=./Admin.NET.db",
                 "EnableInitDb": true, // 启用库表初始化
                 "EnableInitDb": true, // 启用库表初始化
                 "EnableDiffLog": false // 启用库表差异日志
                 "EnableDiffLog": false // 启用库表差异日志
             }
             }
-            //{
-            //    "ConfigId": "test",
-            //    "DbType": "Sqlite",
-            //    "ConnectionString": "DataSource=./Test.db",
-            //    "EnableInitDb": true, // 启用库表初始化
-            //    "EnableDiffLog": false // 启用库表差异日志
-            //}
         ]
         ]
     }
     }
 }
 }

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

@@ -25,13 +25,13 @@
     <PackageReference Include="NETCore.MailKit" Version="2.1.0" />
     <PackageReference Include="NETCore.MailKit" Version="2.1.0" />
     <PackageReference Include="NewLife.Redis" Version="5.0.2022.1101" />
     <PackageReference Include="NewLife.Redis" Version="5.0.2022.1101" />
     <PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.1.9" />
     <PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.1.9" />
-    <PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="2.20.1" />
+    <PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="2.20.2" />
     <PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="2.13.1" />
     <PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="2.13.1" />
     <PackageReference Include="SqlSugarCore" Version="5.1.3.32" />
     <PackageReference Include="SqlSugarCore" Version="5.1.3.32" />
     <PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.23" />
     <PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.23" />
     <PackageReference Include="UAParser" Version="3.1.47" />
     <PackageReference Include="UAParser" Version="3.1.47" />
     <PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
     <PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
-    <PackageReference Include="Masuit.Tools.Core" Version="2.5.7.6" />
+    <PackageReference Include="Masuit.Tools.Core" Version="2.5.7.7" />
   </ItemGroup>
   </ItemGroup>
 
 
   <ItemGroup>
   <ItemGroup>

+ 1 - 13
Admin.NET/Admin.NET.Core/Admin.NET.Core.xml

@@ -229,7 +229,7 @@
         </member>
         </member>
         <member name="F:Admin.NET.Core.SqlSugarConst.ConfigId">
         <member name="F:Admin.NET.Core.SqlSugarConst.ConfigId">
             <summary>
             <summary>
-            默认数据库标识
+            默认数据库标识(默认租户)
             </summary>
             </summary>
         </member>
         </member>
         <member name="F:Admin.NET.Core.SqlSugarConst.PrimaryKey">
         <member name="F:Admin.NET.Core.SqlSugarConst.PrimaryKey">
@@ -237,11 +237,6 @@
             默认表主键
             默认表主键
             </summary>
             </summary>
         </member>
         </member>
-        <member name="F:Admin.NET.Core.SqlSugarConst.TenantId">
-            <summary>
-            默认租户Id
-            </summary>
-        </member>
         <member name="T:Admin.NET.Core.EntityBaseId">
         <member name="T:Admin.NET.Core.EntityBaseId">
             <summary>
             <summary>
             框架实体基类Id
             框架实体基类Id
@@ -6860,13 +6855,6 @@
             <param name="db"></param>
             <param name="db"></param>
             <param name="config"></param>
             <param name="config"></param>
         </member>
         </member>
-        <member name="M:Admin.NET.Core.SqlSugarSetup.InitTenantConnection(SqlSugar.ITenant,System.Int64)">
-            <summary>
-            初始化租户库连接
-            </summary>
-            <param name="iTenant"></param>
-            <param name="tenantId"></param>
-        </member>
         <member name="M:Admin.NET.Core.SqlSugarSetup.InitTenantDatabase(SqlSugar.ITenant,Admin.NET.Core.DbConnectionConfig)">
         <member name="M:Admin.NET.Core.SqlSugarSetup.InitTenantDatabase(SqlSugar.ITenant,Admin.NET.Core.DbConnectionConfig)">
             <summary>
             <summary>
             初始化租户业务数据库
             初始化租户业务数据库

+ 2 - 7
Admin.NET/Admin.NET.Core/Const/SqlSugarConst.cs

@@ -6,17 +6,12 @@
 public class SqlSugarConst
 public class SqlSugarConst
 {
 {
     /// <summary>
     /// <summary>
-    /// 默认数据库标识
+    /// 默认数据库标识(默认租户)
     /// </summary>
     /// </summary>
-    public const string ConfigId = "default";
+    public const string ConfigId = "123456780000000";
 
 
     /// <summary>
     /// <summary>
     /// 默认表主键
     /// 默认表主键
     /// </summary>
     /// </summary>
     public const string PrimaryKey = "Id";
     public const string PrimaryKey = "Id";
-
-    /// <summary>
-    /// 默认租户Id
-    /// </summary>
-    public const string TenantId = "TenantId";
 }
 }

+ 1 - 1
Admin.NET/Admin.NET.Core/SeedData/SysTenantSeedData.cs

@@ -14,7 +14,7 @@ public class SysTenantSeedData : ISqlSugarEntitySeedData<SysTenant>
     {
     {
         return new[]
         return new[]
         {
         {
-            new SysTenant{ Id=123456780000000, Name="系统默认", AdminName="Administrator", Host="www.dilon.vip", Email="zuohuaijun@163.com", Phone="18020030720", TenantType=TenantTypeEnum.Db, DbType=SqlSugar.DbType.Sqlite, Connection="DataSource=./Admin.NET.db", ConfigId=SqlSugarConst.ConfigId, Remark="系统默认", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
+            new SysTenant{ Id=123456780000000, Name="系统默认", AdminName="Administrator", Host="www.dilon.vip", Email="zuohuaijun@163.com", Phone="18020030720", TenantType=TenantTypeEnum.Id, DbType=SqlSugar.DbType.Sqlite, Connection="DataSource=./Admin.NET.db", ConfigId=SqlSugarConst.ConfigId, Remark="系统默认", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
         };
         };
     }
     }
 }
 }

+ 7 - 1
Admin.NET/Admin.NET.Core/Service/DataBase/SysDataBaseService.cs

@@ -22,7 +22,13 @@ public class SysDatabaseService : IDynamicApiController, ITransient
     [HttpGet("/sysDatabase/list")]
     [HttpGet("/sysDatabase/list")]
     public List<dynamic> GetDbList()
     public List<dynamic> GetDbList()
     {
     {
-        return App.GetOptions<DbConnectionOptions>().ConnectionConfigs.Select(u => u.ConfigId).ToList();
+        var connectionConfigs = App.GetOptions<DbConnectionOptions>().ConnectionConfigs;
+        foreach (var config in connectionConfigs)
+        {
+            if (string.IsNullOrWhiteSpace(config.ConfigId))
+                config.ConfigId = SqlSugarConst.ConfigId;
+        }
+        return connectionConfigs.Select(u => u.ConfigId).ToList();
     }
     }
 
 
     /// <summary>
     /// <summary>

+ 22 - 3
Admin.NET/Admin.NET.Core/Service/Tenant/SysTenantService.cs

@@ -84,6 +84,10 @@ public class SysTenantService : IDynamicApiController, ITransient
         isExist = await _userRep.AsQueryable().Filter(null, true).AnyAsync(u => u.Account == input.AdminName);
         isExist = await _userRep.AsQueryable().Filter(null, true).AnyAsync(u => u.Account == input.AdminName);
         if (isExist) throw Oops.Oh(ErrorCodeEnum.D1301);
         if (isExist) throw Oops.Oh(ErrorCodeEnum.D1301);
 
 
+        // ID隔离时设置与主库一致
+        if (input.TenantType == TenantTypeEnum.Id)
+            input.DbType = _tenantRep.AsSugarClient().CurrentConnectionConfig.DbType;
+
         var tenant = input.Adapt<SysTenant>();
         var tenant = input.Adapt<SysTenant>();
         await _tenantRep.InsertAsync(tenant);
         await _tenantRep.InsertAsync(tenant);
         await UpdateTenantCache();
         await UpdateTenantCache();
@@ -196,15 +200,16 @@ public class SysTenantService : IDynamicApiController, ITransient
     [HttpPost("/sysTenant/delete")]
     [HttpPost("/sysTenant/delete")]
     public async Task DeleteTenant(DeleteTenantInput input)
     public async Task DeleteTenant(DeleteTenantInput input)
     {
     {
-        var users = await _userRep.AsQueryable().Filter(null, true).Where(u => u.TenantId == input.Id).ToListAsync();
-        // 超级管理员所在租户为默认租户
-        if (users.Any(u => u.AccountType == AccountTypeEnum.SuperAdmin))
+        // 禁止删除默认租户
+        if (input.Id.ToString() == SqlSugarConst.ConfigId)
             throw Oops.Oh(ErrorCodeEnum.D1023);
             throw Oops.Oh(ErrorCodeEnum.D1023);
+
         var entity = await _tenantRep.GetFirstAsync(u => u.Id == input.Id);
         var entity = await _tenantRep.GetFirstAsync(u => u.Id == input.Id);
         await _tenantRep.DeleteAsync(entity);
         await _tenantRep.DeleteAsync(entity);
         await UpdateTenantCache();
         await UpdateTenantCache();
 
 
         // 删除与租户相关的表数据
         // 删除与租户相关的表数据
+        var users = await _userRep.AsQueryable().Filter(null, true).Where(u => u.TenantId == input.Id).ToListAsync();
         var userIds = users.Select(u => u.Id).ToList();
         var userIds = users.Select(u => u.Id).ToList();
         await _userRep.AsDeleteable().Where(u => userIds.Contains(u.Id)).ExecuteCommandAsync();
         await _userRep.AsDeleteable().Where(u => userIds.Contains(u.Id)).ExecuteCommandAsync();
 
 
@@ -330,6 +335,20 @@ public class SysTenantService : IDynamicApiController, ITransient
         _sysCacheService.Remove(CacheConst.KeyTenant);
         _sysCacheService.Remove(CacheConst.KeyTenant);
 
 
         var tenantList = await _tenantRep.GetListAsync();
         var tenantList = await _tenantRep.GetListAsync();
+        var defautTenant = tenantList.FirstOrDefault(u => u.Id.ToString() == SqlSugarConst.ConfigId);
+        foreach (var tenant in tenantList)
+        {
+            if (tenant.Id.ToString() == SqlSugarConst.ConfigId) continue;
+
+            // Id模式隔离的租户数据库与主租户一致
+            if (tenant.TenantType == TenantTypeEnum.Id)
+            {
+                tenant.ConfigId = tenant.Id.ToString();
+                tenant.DbType = defautTenant.DbType;
+                tenant.Connection = defautTenant.Connection;
+            }
+        }
+
         _sysCacheService.Set(CacheConst.KeyTenant, tenantList);
         _sysCacheService.Set(CacheConst.KeyTenant, tenantList);
     }
     }
 
 

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

@@ -16,7 +16,21 @@ public class SqlSugarRepository<T> : SimpleClient<T> where T : class, new()
         if (typeof(T).IsDefined(typeof(TenantBusinessAttribute), false))
         if (typeof(T).IsDefined(typeof(TenantBusinessAttribute), false))
         {
         {
             var tenantId = App.GetRequiredService<UserManager>().TenantId; // 根据租户Id切库
             var tenantId = App.GetRequiredService<UserManager>().TenantId; // 根据租户Id切库
-            base.Context = SqlSugarSetup.InitTenantConnection(iTenant, tenantId);
+
+            if (!iTenant.IsAnyConnection(tenantId.ToString()))
+            {
+                var tenant = App.GetRequiredService<SysCacheService>().Get<List<SysTenant>>(CacheConst.KeyTenant)
+                    .FirstOrDefault(u => u.Id == tenantId);
+                iTenant.AddConnection(new ConnectionConfig()
+                {
+                    ConfigId = tenant.Id,
+                    DbType = tenant.DbType,
+                    ConnectionString = tenant.Connection,
+                    IsAutoCloseConnection = true
+                });
+                SqlSugarSetup.SetDbAop(iTenant.GetConnectionScope(tenantId.ToString()));
+            }
+            base.Context = iTenant.GetConnectionScope(tenantId.ToString());
         }
         }
         else
         else
         {
         {

+ 15 - 29
Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarSetup.cs

@@ -39,6 +39,9 @@ public static class SqlSugarSetup
     /// <param name="config"></param>
     /// <param name="config"></param>
     public static void SetDbConfig(DbConnectionConfig config)
     public static void SetDbConfig(DbConnectionConfig config)
     {
     {
+        if (string.IsNullOrWhiteSpace(config.ConfigId))
+            config.ConfigId = SqlSugarConst.ConfigId;
+
         var configureExternalServices = new ConfigureExternalServices
         var configureExternalServices = new ConfigureExternalServices
         {
         {
             EntityService = (type, column) => // 修改列可空-1、带?问号 2、String类型若没有Required
             EntityService = (type, column) => // 修改列可空-1、带?问号 2、String类型若没有Required
@@ -232,28 +235,6 @@ public static class SqlSugarSetup
         }
         }
     }
     }
 
 
-    /// <summary>
-    /// 初始化租户库连接
-    /// </summary>
-    /// <param name="iTenant"></param>
-    /// <param name="tenantId"></param>
-    public static SqlSugarScopeProvider InitTenantConnection(ITenant iTenant, long tenantId)
-    {
-        var tenant = App.GetRequiredService<SysCacheService>().Get<List<SysTenant>>(CacheConst.KeyTenant).FirstOrDefault(u => u.Id == tenantId);
-        if (!iTenant.IsAnyConnection(tenantId.ToString()))
-        {
-            iTenant.AddConnection(new ConnectionConfig()
-            {
-                ConfigId = tenantId.ToString(),
-                ConnectionString = tenant.Connection,
-                DbType = tenant.DbType,
-                IsAutoCloseConnection = true
-            });
-            SetDbAop(iTenant.GetConnectionScope(tenantId.ToString()));
-        }
-        return iTenant.GetConnectionScope(tenantId.ToString());
-    }
-
     /// <summary>
     /// <summary>
     /// 初始化租户业务数据库
     /// 初始化租户业务数据库
     /// </summary>
     /// </summary>
@@ -306,7 +287,7 @@ public static class SqlSugarSetup
                     (tAtt == null && (string)db.CurrentConnectionConfig.ConfigId != SqlSugarConst.ConfigId))
                     (tAtt == null && (string)db.CurrentConnectionConfig.ConfigId != SqlSugarConst.ConfigId))
                     continue;
                     continue;
 
 
-                Expression<Func<EntityBaseData, bool>> dynamicExpression = u => u.IsDelete == false;
+                Expression<Func<EntityBase, bool>> dynamicExpression = u => u.IsDelete == false;
                 var tableFilterItem = new TableFilterItem<object>(entityType, dynamicExpression);
                 var tableFilterItem = new TableFilterItem<object>(entityType, dynamicExpression);
                 tableFilterItems.Add(tableFilterItem);
                 tableFilterItems.Add(tableFilterItem);
                 db.QueryFilter.Add(tableFilterItem);
                 db.QueryFilter.Add(tableFilterItem);
@@ -337,17 +318,22 @@ public static class SqlSugarSetup
         {
         {
             // 获取租户实体数据表
             // 获取租户实体数据表
             var entityTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
             var entityTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
-                && u.BaseType == typeof(EntityTenant));
+                && (u.BaseType == typeof(EntityTenant) || u.BaseType == typeof(EntityTenantId)));
             if (!entityTypes.Any()) return;
             if (!entityTypes.Any()) return;
 
 
             var tableFilterItems = new List<TableFilterItem<object>>();
             var tableFilterItems = new List<TableFilterItem<object>>();
             foreach (var entityType in entityTypes)
             foreach (var entityType in entityTypes)
             {
             {
-                // 排除非当前数据库实体
-                var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
-                if ((tAtt != null && (string)db.CurrentConnectionConfig.ConfigId != tAtt.configId.ToString()) ||
-                    (tAtt == null && (string)db.CurrentConnectionConfig.ConfigId != SqlSugarConst.ConfigId))
-                    continue;
+                // 获取库隔离租户业务实体
+                var tenantBusinessAtt = entityType.GetCustomAttribute<TenantBusinessAttribute>();
+                if (tenantBusinessAtt == null)
+                {
+                    // 排除非当前数据库实体
+                    var tenantAtt = entityType.GetCustomAttribute<TenantAttribute>();
+                    if ((tenantAtt != null && (string)db.CurrentConnectionConfig.ConfigId != tenantAtt.configId.ToString()) ||
+                        (tenantAtt == null && (string)db.CurrentConnectionConfig.ConfigId != SqlSugarConst.ConfigId))
+                        continue;
+                }
 
 
                 Expression<Func<EntityTenant, bool>> dynamicExpression = u => u.TenantId == long.Parse(tenantId);
                 Expression<Func<EntityTenant, bool>> dynamicExpression = u => u.TenantId == long.Parse(tenantId);
                 var tableFilterItem = new TableFilterItem<object>(entityType, dynamicExpression);
                 var tableFilterItem = new TableFilterItem<object>(entityType, dynamicExpression);

+ 2 - 2
Web/src/views/system/cache/index.vue

@@ -2,7 +2,7 @@
 	<div class="sys-cache-container">
 	<div class="sys-cache-container">
 		<NoticeBar text="系统缓存数据管理,请慎重操作!" leftIcon="iconfont icon-tongzhi2" background="var(--el-color-primary-light-9)" color="var(--el-color-primary)" />
 		<NoticeBar text="系统缓存数据管理,请慎重操作!" leftIcon="iconfont icon-tongzhi2" background="var(--el-color-primary-light-9)" color="var(--el-color-primary)" />
 		<el-row :gutter="8" style="width: 100%">
 		<el-row :gutter="8" style="width: 100%">
-			<el-col :span="4" :xs="24">
+			<el-col :span="8" :xs="24">
 				<el-card shadow="hover" header="缓存列表" v-loading="loading" class="mt8">
 				<el-card shadow="hover" header="缓存列表" v-loading="loading" class="mt8">
 					<template #header>
 					<template #header>
 						<div class="card-header">
 						<div class="card-header">
@@ -25,7 +25,7 @@
 					/>
 					/>
 				</el-card>
 				</el-card>
 			</el-col>
 			</el-col>
-			<el-col :span="20" :xs="24">
+			<el-col :span="16" :xs="24">
 				<el-card shadow="hover" header="缓存数据" v-loading="loading1" class="mt8">
 				<el-card shadow="hover" header="缓存数据" v-loading="loading1" class="mt8">
 					<template #header>
 					<template #header>
 						<div class="card-header">
 						<div class="card-header">

+ 1 - 1
Web/src/views/system/database/component/addTable.vue

@@ -127,7 +127,7 @@ export default defineComponent({
 
 
 		// 关闭弹窗
 		// 关闭弹窗
 		const closeDialog = () => {
 		const closeDialog = () => {
-			mittBus.emit('addTableSubmitted', state.ruleForm.tableName);
+			mittBus.emit('addTableSubmitted', state.ruleForm.tableName ?? '');
 			state.tableData = [];
 			state.tableData = [];
 			state.isShowDialog = false;
 			state.isShowDialog = false;
 		};
 		};

+ 1 - 1
Web/src/views/system/formDes/index.vue

@@ -13,7 +13,7 @@ export default defineComponent({
 	setup() {
 	setup() {
 		const vFormDesignRef = ref(null);
 		const vFormDesignRef = ref(null);
 		const state = reactive({
 		const state = reactive({
-			loading: true,
+			loading: false,
 		});
 		});
 
 
 		return {
 		return {

+ 1 - 1
Web/src/views/system/log/exlog/index.vue

@@ -19,7 +19,7 @@
 		<el-card shadow="hover" style="margin-top: 8px">
 		<el-card shadow="hover" style="margin-top: 8px">
 			<el-table :data="logData" style="width: 100%" v-loading="loading" border>
 			<el-table :data="logData" style="width: 100%" v-loading="loading" border>
 				<el-table-column type="index" label="序号" width="55" align="center" />
 				<el-table-column type="index" label="序号" width="55" align="center" />
-				<el-table-column prop="logName" label="记录器类别名称" show-overflow-tooltip />
+				<el-table-column prop="logName" label="类别名称" show-overflow-tooltip />
 				<el-table-column prop="logLevel" label="日志级别" show-overflow-tooltip />
 				<el-table-column prop="logLevel" label="日志级别" show-overflow-tooltip />
 				<el-table-column prop="eventId" label="事件Id" show-overflow-tooltip />
 				<el-table-column prop="eventId" label="事件Id" show-overflow-tooltip />
 				<el-table-column prop="message" label="日志消息" show-overflow-tooltip />
 				<el-table-column prop="message" label="日志消息" show-overflow-tooltip />

+ 1 - 6
Web/src/views/system/log/oplog/index.vue

@@ -19,7 +19,7 @@
 		<el-card shadow="hover" style="margin-top: 8px">
 		<el-card shadow="hover" style="margin-top: 8px">
 			<el-table :data="logData" style="width: 100%" v-loading="loading" border>
 			<el-table :data="logData" style="width: 100%" v-loading="loading" border>
 				<el-table-column type="index" label="序号" width="55" align="center" />
 				<el-table-column type="index" label="序号" width="55" align="center" />
-				<el-table-column prop="logName" label="记录器类别名称" show-overflow-tooltip />
+				<el-table-column prop="logName" label="类别名称" show-overflow-tooltip />
 				<el-table-column prop="logLevel" label="日志级别" show-overflow-tooltip />
 				<el-table-column prop="logLevel" label="日志级别" show-overflow-tooltip />
 				<el-table-column prop="eventId" label="事件Id" show-overflow-tooltip />
 				<el-table-column prop="eventId" label="事件Id" show-overflow-tooltip />
 				<el-table-column prop="message" label="日志消息" show-overflow-tooltip />
 				<el-table-column prop="message" label="日志消息" show-overflow-tooltip />
@@ -54,11 +54,6 @@
 				</div>
 				</div>
 			</template>
 			</template>
 			<pre>{{ content }}</pre>
 			<pre>{{ content }}</pre>
-			<template #footer>
-				<span class="dialog-footer">
-					<el-button type="primary" @click="dialogVisible = false">确认</el-button>
-				</span>
-			</template>
 		</el-dialog>
 		</el-dialog>
 	</div>
 	</div>
 </template>
 </template>

+ 1 - 1
Web/src/views/system/tenant/component/editTenant.vue

@@ -11,7 +11,7 @@
 				<el-row :gutter="35">
 				<el-row :gutter="35">
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 						<el-form-item label="租户类型" :rules="[{ required: true, message: '租户类型不能为空', trigger: 'blur' }]">
 						<el-form-item label="租户类型" :rules="[{ required: true, message: '租户类型不能为空', trigger: 'blur' }]">
-							<el-radio-group v-model="ruleForm.tenantType">
+							<el-radio-group v-model="ruleForm.tenantType" :disabled="ruleForm.id != undefined">
 								<el-radio :label="0">ID隔离</el-radio>
 								<el-radio :label="0">ID隔离</el-radio>
 								<el-radio :label="1">库隔离</el-radio>
 								<el-radio :label="1">库隔离</el-radio>
 							</el-radio-group>
 							</el-radio-group>

+ 4 - 18
Web/src/views/system/tenant/component/grantMenu.vue

@@ -1,13 +1,7 @@
 <template>
 <template>
 	<div class="sys-grantMenu-container">
 	<div class="sys-grantMenu-container">
-		<el-dialog v-model="isShowDialog" draggable width="769px">
-			<template #header>
-				<div style="color: #fff">
-					<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
-					<span> 授权租户菜单 </span>
-				</div>
-			</template>
-			<el-form :model="ruleForm" size="default">
+		<el-dialog v-model="isShowDialog" title="授权租户菜单" draggable width="769px">
+			<el-form :model="ruleForm" size="default" v-loading="loading">
 				<el-row :gutter="35">
 				<el-row :gutter="35">
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl1="24">
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl1="24">
 						<el-form-item prop="orgIdList" label="">
 						<el-form-item prop="orgIdList" label="">
@@ -18,9 +12,8 @@
 								show-checkbox
 								show-checkbox
 								:props="{ children: 'children', label: 'title', class: treeNodeClass }"
 								:props="{ children: 'children', label: 'title', class: treeNodeClass }"
 								:default-checked-keys="ownMenuData"
 								:default-checked-keys="ownMenuData"
-								highlight-current
-								class="menu-data-tree"
 								icon="ele-Menu"
 								icon="ele-Menu"
+								highlight-current
 								default-expand-all
 								default-expand-all
 							/>
 							/>
 						</el-form-item>
 						</el-form-item>
@@ -51,7 +44,7 @@ export default defineComponent({
 	setup() {
 	setup() {
 		const treeRef = ref<InstanceType<typeof ElTree>>();
 		const treeRef = ref<InstanceType<typeof ElTree>>();
 		const state = reactive({
 		const state = reactive({
-			loading: true,
+			loading: false,
 			isShowDialog: false,
 			isShowDialog: false,
 			ruleForm: {
 			ruleForm: {
 				id: 0,
 				id: 0,
@@ -109,13 +102,6 @@ export default defineComponent({
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">
-.menu-data-tree {
-	width: 100%;
-	// border: 1px solid var(--el-border-color);
-	border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
-	padding: 5px;
-}
-
 :deep(.penultimate-node) {
 :deep(.penultimate-node) {
 	.el-tree-node__children {
 	.el-tree-node__children {
 		padding-left: 40px;
 		padding-left: 40px;

+ 2 - 2
Web/src/views/system/tenant/index.vue

@@ -23,8 +23,8 @@
 				<el-table-column prop="adminName" label="管理员" width="120" show-overflow-tooltip />
 				<el-table-column prop="adminName" label="管理员" width="120" show-overflow-tooltip />
 				<el-table-column prop="phone" label="电话" width="120" show-overflow-tooltip />
 				<el-table-column prop="phone" label="电话" width="120" show-overflow-tooltip />
 				<!-- <el-table-column prop="host" label="主机" show-overflow-tooltip /> -->
 				<!-- <el-table-column prop="host" label="主机" show-overflow-tooltip /> -->
-				<el-table-column prop="email" label="邮箱" show-overflow-tooltip />
-				<el-table-column prop="tenantType" label="租户类型" align="center" show-overflow-tooltip>
+				<!-- <el-table-column prop="email" label="邮箱" show-overflow-tooltip /> -->
+				<el-table-column prop="tenantType" label="租户类型" width="100" align="center" show-overflow-tooltip>
 					<template #default="scope">
 					<template #default="scope">
 						<el-tag v-if="scope.row.tenantType === 0"> ID隔离 </el-tag>
 						<el-tag v-if="scope.row.tenantType === 0"> ID隔离 </el-tag>
 						<el-tag type="danger" v-else> 库隔离 </el-tag>
 						<el-tag type="danger" v-else> 库隔离 </el-tag>