From e2eecb54d9d971161508a82fc387faa3fa4f1ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=B5=E4=BD=A0=E4=B8=AA=E6=B1=AA=E5=91=80?= Date: Wed, 3 Sep 2025 16:14:34 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8D=92=20perf(Core):=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E8=A7=86=E5=9B=BE=EF=BC=8C=E6=94=B9=E7=94=B1=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=9D=83=E9=99=90=E7=9B=B8=E5=85=B3=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Admin.NET/Admin.NET.Core/Const/CacheConst.cs | 5 + Admin.NET/Admin.NET.Core/Entity/SysApiInfo.cs | 63 ----- .../Admin.NET.Core/Entity/VSysPermissions.cs | 58 ----- .../Admin.NET.Core/Entity/VSysUserOrg.cs | 82 ------- .../Admin.NET.Core/Job/StartHostedService.cs | 7 - .../Logging/ElasticSearchLoggingWriter.cs | 4 +- .../Service/Auth/SysAuthService.cs | 231 ++++++++++++------ .../Service/Common/Dto/ApiOutput.cs | 14 +- .../Service/Common/SysCommonService.cs | 20 +- .../Service/User/UserManager.cs | 4 +- .../Service/User/UserSessionDao.cs | 7 +- .../Admin.NET.Core/SqlSugar/SqlSugarFilter.cs | 4 +- 12 files changed, 192 insertions(+), 307 deletions(-) delete mode 100644 Admin.NET/Admin.NET.Core/Entity/SysApiInfo.cs delete mode 100644 Admin.NET/Admin.NET.Core/Entity/VSysPermissions.cs delete mode 100644 Admin.NET/Admin.NET.Core/Entity/VSysUserOrg.cs diff --git a/Admin.NET/Admin.NET.Core/Const/CacheConst.cs b/Admin.NET/Admin.NET.Core/Const/CacheConst.cs index 1cbee198..43a1c11b 100644 --- a/Admin.NET/Admin.NET.Core/Const/CacheConst.cs +++ b/Admin.NET/Admin.NET.Core/Const/CacheConst.cs @@ -11,6 +11,11 @@ namespace Admin.NET.Core; /// public class CacheConst { + /// + /// 接口信息缓存 + /// + public const string KeyAllApi = "sys_all_api"; + /// /// 用户会话缓存 /// diff --git a/Admin.NET/Admin.NET.Core/Entity/SysApiInfo.cs b/Admin.NET/Admin.NET.Core/Entity/SysApiInfo.cs deleted file mode 100644 index 572b99ee..00000000 --- a/Admin.NET/Admin.NET.Core/Entity/SysApiInfo.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 -// -// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 -// -// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! - -namespace Admin.NET.Core; - -/// -/// 系统接口信息表 -/// -[SysTable] -[SugarTable(null, "系统接口信息表")] -public partial class SysApiInfo : EntityBaseId -{ - /// - /// 组名 - /// - [SugarColumn(ColumnDescription = "组名", Length = 64)] - public string? GroupName { get; set; } - - /// - /// 路由名 - /// - [SugarColumn(ColumnDescription = "路由名", Length = 64)] - public string? Name { get; set; } - - /// - /// 描述 - /// - [SugarColumn(ColumnDescription = "描述", Length = 64)] - public string? Desc { get; set; } - - /// - /// 路由 - /// - [SugarColumn(ColumnDescription = "路由", Length = 64)] - public string Route { get; set; } - - /// - /// 控制器名称 - /// - [SugarColumn(ColumnDescription = "控制器名称", Length = 64)] - public string Action { get; set; } - - /// - /// 请求方式 - /// - [SugarColumn(ColumnDescription = "请求方式", Length = 16)] - public string HttpMethod { get; set; } - - /// - /// 是否移动端接口 - /// - [SugarColumn(ColumnDescription = "是否移动端接口")] - public bool IsAppApi { get; set; } - - /// - /// 排序 - /// - [SugarColumn(ColumnDescription = "排序")] - public int Order { get; set; } = 100; -} \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/Entity/VSysPermissions.cs b/Admin.NET/Admin.NET.Core/Entity/VSysPermissions.cs deleted file mode 100644 index ddd4136e..00000000 --- a/Admin.NET/Admin.NET.Core/Entity/VSysPermissions.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 -// -// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 -// -// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! - -namespace Admin.NET.Core; - -/// -/// 系统权限标识视图 -/// -[SugarTable(null, "系统权限标识视图"), IgnoreTable] -public class VSysPermissions : ISqlSugarView -{ - /// - /// 来自菜单标识 - /// - [SugarColumn(ColumnDescription = "来自菜单标识")] - public long MenuId { get; set; } - - /// - /// 状态 - /// - [SugarColumn(ColumnDescription = "状态")] - public StatusEnum Status { get; set; } - - /// - /// 权限标识 - /// - [SugarColumn(ColumnDescription = "权限标识", IsPrimaryKey = true)] - public string Permission { get; set; } - - /// - /// 视图语句 - /// - public string GetQueryableSqlString(SqlSugarScopeProvider db) - { - return db.Union( - db.Queryable() - .Where(u => u.Type == MenuTypeEnum.Btn && u.Status == StatusEnum.Enable && !string.IsNullOrWhiteSpace(u.Permission)) - .Select(u => new VSysPermissions - { - MenuId = u.Id, - Status = u.Status, - Permission = u.Permission - }), - db.Queryable() - .Where(u => !string.IsNullOrWhiteSpace(u.Route) && SqlFunc.Subqueryable().Where(z => z.Permission == u.Route).NotAny()) - .Select(u => new VSysPermissions - { - MenuId = 0, - Status = StatusEnum.Enable, - Permission = u.Route, - }).Distinct()) - .OrderBy(u => u.Permission) - .ToMappedSqlString(); - } -} \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/Entity/VSysUserOrg.cs b/Admin.NET/Admin.NET.Core/Entity/VSysUserOrg.cs deleted file mode 100644 index cddce390..00000000 --- a/Admin.NET/Admin.NET.Core/Entity/VSysUserOrg.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 -// -// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 -// -// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! - -namespace Admin.NET.Core; - -/// -/// 系统用户机构视图 -/// -[SugarTable(null, "系统用户机构视图"), IgnoreTable] -public class VSysUserOrg : ISqlSugarView -{ - /// - /// 用户Id - /// - [SugarColumn(ColumnDescription = "用户Id")] - public long UserId { get; set; } - - /// - /// 机构Id - /// - [SugarColumn(ColumnDescription = "机构Id")] - public long OrgId { get; set; } - - /// - /// 视图语句 - /// - public string GetQueryableSqlString(SqlSugarScopeProvider db) - { - return db.Union( - // 获取用户表中的机构Id - db.Queryable().IgnoreTenant() - .Select(u => new VSysUserOrg - { - UserId = u.Id, - OrgId = u.OrgId - }), - // 获取用户创建的机构Id - db.Queryable().IgnoreTenant() - .Where(u => u.CreateUserId != null) - .Select(u => new VSysUserOrg - { - UserId = u.CreateUserId.Value, - OrgId = u.Id - }), - // 获取用户扩展机构Id - db.Queryable() - .Select(u => new VSysUserOrg - { - UserId = u.UserId, - OrgId = u.OrgId - }), - // 获取用户角色关联的机构Id - db.Queryable() - .InnerJoin((u, a) => u.RoleId == a.RoleId) - .Select((u, a) => new VSysUserOrg - { - UserId = a.UserId, - OrgId = u.OrgId - }), - // 获取包含全部数据权限的机构Id - db.Queryable().IgnoreTenant() - .FullJoin((u, a) => a.SysRole.DataScope == DataScopeEnum.All) - .Select((u, a) => new VSysUserOrg - { - UserId = a.UserId, - OrgId = u.Id - }), - // 超管获取全部机构Id - db.Queryable().IgnoreTenant() - .FullJoin((u, a) => a.AccountType == AccountTypeEnum.SuperAdmin) - .Select((u, a) => new VSysUserOrg - { - UserId = a.Id, - OrgId = u.Id - })) - .Where(u => u.OrgId != null && u.OrgId != 0) - .ToMappedSqlString(); - } -} \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/Job/StartHostedService.cs b/Admin.NET/Admin.NET.Core/Job/StartHostedService.cs index 87ffc73e..99e334c0 100644 --- a/Admin.NET/Admin.NET.Core/Job/StartHostedService.cs +++ b/Admin.NET/Admin.NET.Core/Job/StartHostedService.cs @@ -41,13 +41,6 @@ public class StartHostedService(IServiceScopeFactory serviceScopeFactory) : IHos Console.WriteLine(message); Log.Information(message); - // 持久化系统接口数据 - var sysAuthService = serviceScope.ServiceProvider.GetRequiredService(); - await sysAuthService.ResetSysApiInfo(); - message = $"【启动任务】持久化系统接口数据 {DateTime.Now}"; - Console.WriteLine(message); - Log.Information(message); - Console.ForegroundColor = originColor; }, cancellationToken); } diff --git a/Admin.NET/Admin.NET.Core/Logging/ElasticSearchLoggingWriter.cs b/Admin.NET/Admin.NET.Core/Logging/ElasticSearchLoggingWriter.cs index d496f9c5..09411d7a 100644 --- a/Admin.NET/Admin.NET.Core/Logging/ElasticSearchLoggingWriter.cs +++ b/Admin.NET/Admin.NET.Core/Logging/ElasticSearchLoggingWriter.cs @@ -42,7 +42,7 @@ public class ElasticSearchLoggingWriter : IDatabaseLoggingWriter, IDisposable return; // 获取当前操作者 - var userManager = LazyHelper.GetService().Value; + var userManager = LazyHelper.GetService(); string account = "", realName = "", userId = "", tenantId = ""; if (loggingMonitor.authorizationClaims != null) { @@ -51,7 +51,7 @@ public class ElasticSearchLoggingWriter : IDatabaseLoggingWriter, IDisposable { if (item.type != ClaimConst.UserId) continue; userId = item.value; - userSession = userManager.GetSessionOrRefresh(userId); + userSession = userManager.Value.GetSessionOrRefresh(userId); break; } tenantId = userSession?.TenantId.ToString(); diff --git a/Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs b/Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs index 688b2b36..fd6db69e 100644 --- a/Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs +++ b/Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs @@ -294,28 +294,16 @@ public class SysAuthService : IDynamicApiController, ITransient user.SysPos ??= await db.Queryable().FirstAsync(u => u.Id == user.PosId); user.SysOrg ??= await db.Queryable().FirstAsync(u => u.Id == user.OrgId); - var orgIds = await db.Queryable().Where(u => u.UserId == user.Id).Select(u => u.OrgId).ToListAsync(); var roleIds = await db.Queryable().InnerJoinIF(user.AccountType != AccountTypeEnum.SuperAdmin, (u, a) => a.RoleId == u.Id && a.UserId == user.Id).Select((u, a) => u.Id).ToListAsync(); var posIds = await db.Queryable().InnerJoinIF(user.AccountType != AccountTypeEnum.SuperAdmin, (u, a) => a.PosId == u.Id && a.UserId == user.Id).Select((u, a) => u.Id).ToListAsync(); posIds = posIds.Concat([user.PosId]).Where(u => u != 0).ToList(); - var maxDataScope = await db.Queryable().Where(u => roleIds.Contains(u.Id)).MinAsync(u => u.DataScope); - if (maxDataScope == 0) maxDataScope = DataScopeEnum.Self; + var maxDataScope = await db.Queryable().Where(u => roleIds.Contains(u.Id)).Select(u => u.DataScope).ToListAsync(); + if (!maxDataScope.Any()) maxDataScope = [DataScopeEnum.Self]; - var permissions = user.AccountType != AccountTypeEnum.SuperAdmin ? await db.Queryable() - .InnerJoin((u, a) => roleIds.Contains(a.RoleId) && u.MenuId == a.MenuId) - .InnerJoin((u, a, b) => u.Permission != b.Route) - .Select(u => u.Permission) - .ToListAsync() - : await db.Queryable().Select(u => u.Permission).ToListAsync(); - - var unauthorizedPermissions = user.AccountType != AccountTypeEnum.SuperAdmin ? await db.Union( - db.Queryable().Where(u => roleIds.Contains(u.RoleId)).Select(u => u.Route), - db.Queryable().Where(u => u.MenuId != 0 && SqlFunc.Subqueryable() - .Where(z => roleIds.Contains(z.RoleId) && z.MenuId == u.MenuId).NotAny()) - .Select(u => u.Permission) - ).ToListAsync() - : []; + var orgIds = GetUserOrgIdList(user, roleIds); + var permissions = GetUserPermissions(user, roleIds); + var unauthorizedPermissions = GetUserUnPermissions(user, roleIds); // 缓存用户Session _userManager.SetSession(new() @@ -341,8 +329,8 @@ public class SysAuthService : IDynamicApiController, ITransient RoleIds = roleIds, Permissions = permissions, UnauthorizedPermissions = unauthorizedPermissions, + DataScopeList = user.AccountType == AccountTypeEnum.SuperAdmin ? [DataScopeEnum.All] : maxDataScope, AppPermissions = loginMode == LoginModeEnum.APP ? LazyHelper.GetService().Value.GetAppApiList() : null, - MaxDataScope = user.AccountType == AccountTypeEnum.SuperAdmin ? DataScopeEnum.All : maxDataScope, ExtProps = App.GetServices().SelectMany(u => u.GetInitExtProps(user)).ToDictionary(u => u.Key, u => u.Value) }); } @@ -495,6 +483,157 @@ public class SysAuthService : IDynamicApiController, ITransient } } + /// + /// 获取系统所有接口列表 + /// + [NonAction] + public List GetSysAllApiInfoList() + { + return _sysCacheService.GetOrAdd(CacheConst.KeyAllApi, _ => + { + var apiList = new List(); + var apiDescriptionGroups = _apiProvider.ApiDescriptionGroups.Items; + foreach (ApiDescriptionGroup group in apiDescriptionGroups) + { + foreach (var action in group.Items) + { + // 控制器信息 + if (action.ActionDescriptor is not ControllerActionDescriptor actionDescriptor) continue; + var apiDescription = actionDescriptor.ControllerTypeInfo.GetCustomAttribute(true); + + // 路由 + var route = action.RelativePath!.Contains('{') ? action.RelativePath[..(action.RelativePath.IndexOf('{') - 1)] : action.RelativePath; // 去掉路由参数 + route = route[(route.IndexOf('/') + 1)..]; // 去掉路由前缀 + + // 获取分组名称和接口名称 + string groupName = null, displayText = null; + foreach (var attr in action.ActionDescriptor.EndpointMetadata) + { + switch (attr) + { + case ApiDescriptionSettingsAttribute settings: + if (!string.IsNullOrWhiteSpace(settings.GroupName)) groupName = settings.GroupName; + break; + case DisplayNameAttribute displayName: + if (!string.IsNullOrWhiteSpace(displayName.DisplayName)) displayText = displayName.DisplayName; + break; + } + } + + apiList.Add(new ApiOutput + { + Route = route, + HttpMethod = action.HttpMethod, + Order = apiDescription?.Order ?? 0, + Action = actionDescriptor.ActionName, + Name = actionDescriptor.ControllerName, + GroupName = groupName ?? group.GroupName, + IsAppApi = actionDescriptor.ControllerTypeInfo.GetCustomAttribute(true) != null, + Desc = displayText ?? (string.IsNullOrWhiteSpace(apiDescription?.Description) ? actionDescriptor.ControllerName : apiDescription?.Description), + }); + } + } + return apiList; + }); + } + + /// + /// 获取用户权限 + /// + /// + /// + /// + private List GetUserPermissions(SysUser user, List roleIds) + { + var superAdmin = user.AccountType == AccountTypeEnum.SuperAdmin; + var db = _sysUserRep.Context.CopyNew(); + + var allApi = GetSysAllApiInfoList().Select(u => u.Route).ToArray(); + var menuPermissions = db.Queryable() + .Where(u => u.Status == StatusEnum.Enable && u.Type == MenuTypeEnum.Btn) + .Select(u => u.Permission) + .Distinct() + .ToList(); + + // 超管返回所有权限 + if (superAdmin) return allApi.Union(menuPermissions).Distinct().Order().ToList(); + + // 普通用户返回已授权标识 + 未不在菜单中的权限标识 + var permissions = db.Queryable() + .InnerJoin((u, a) => u.Id == a.MenuId) + .Where((u, a) => u.Status == StatusEnum.Enable && u.Type == MenuTypeEnum.Btn) + .Where((u, a) => roleIds.Contains(a.RoleId) && SqlFunc.Subqueryable() + .Where(z => roleIds.Contains(z.RoleId) && u.Permission == z.Route).NotAny()) + .Select(u => u.Permission) + .Distinct() + .ToList(); + return allApi.Except(menuPermissions).Union(permissions).Distinct().Order().ToList(); + } + + /// + /// 获取用户不能访问的权限 + /// + /// + /// + /// + private List GetUserUnPermissions(SysUser user, List roleIds) + { + var superAdmin = user.AccountType == AccountTypeEnum.SuperAdmin; + var db = _sysUserRep.Context.CopyNew(); + if (superAdmin) return []; + return db.Union(db.Queryable() + .InnerJoin((u, a) => u.Id == a.MenuId) + .Where((u, a) => u.Status == StatusEnum.Enable && u.Type == MenuTypeEnum.Btn) + .Where((u, a) => !roleIds.Contains(a.RoleId)) + .Select(u => u.Permission), + db.Queryable().Where(u => roleIds.Contains(u.RoleId)).Select(u => u.Route)) + .ToList(); + } + + /// + /// 获取用户已授权的机构Id + /// + /// + /// + /// + private List GetUserOrgIdList(SysUser user, List roleIds) + { + var db = _sysUserRep.Context.CopyNew(); + var orgIds = db.Union( + // 获取用户表中的机构Id + db.Queryable().IgnoreTenant().Select(u => new { UserId = u.Id, u.OrgId }), + // 获取用户创建的机构Id + db.Queryable().IgnoreTenant().Where(u => u.CreateUserId != null).Select(u => new { UserId = u.CreateUserId.Value, OrgId = u.Id }), + // 获取用户扩展机构Id + db.Queryable().Select(u => new { u.UserId, u.OrgId }), + // 获取用户角色关联的机构Id + db.Queryable().InnerJoin((u, a) => u.RoleId == a.RoleId).Select((u, a) => new { a.UserId, u.OrgId }), + // 获取包含全部数据权限的机构Id + db.Queryable().IgnoreTenant().FullJoin((u, a) => a.SysRole.DataScope == DataScopeEnum.All).Select((u, a) => new { a.UserId, OrgId = u.Id }), + // 超管获取全部机构Id + db.Queryable().IgnoreTenant().FullJoin((u, a) => a.AccountType == AccountTypeEnum.SuperAdmin).Select((u, a) => new { UserId = a.Id, OrgId = u.Id })) + .Where(u => SqlFunc.IsNull(u.OrgId, 0) != 0 && u.UserId == user.Id) + .Select(u => u.OrgId) + .Distinct() + .ToList(); + + // 如果存在本部门及以下,则获取本部门及以下机构的Id + var dataScopes = db.Queryable().Where(u => roleIds.Contains(u.Id)).Select(u => u.DataScope).Distinct().ToList(); + if (dataScopes.Any(u => u == DataScopeEnum.DeptChild)) + { + var childOrg = db.Queryable().IgnoreTenant().ToTree(u => u.Children, u => u.Pid, user.OrgId); + if (childOrg == null || childOrg.Count > 0) return orgIds; + var queue = new Queue(childOrg); + while (queue.Count > 0) + { + var org = queue.Dequeue(); + if (org.Children is { Count: > 0 }) queue.EnqueueRange(org.Children); + orgIds.Add(org.Id); + } + } + return orgIds; + } + /// /// 刷新Session /// @@ -505,60 +644,4 @@ public class SysAuthService : IDynamicApiController, ITransient var user = await _sysUserRep.AsQueryable().IgnoreTenant().Includes(u => u.SysOrg).FirstAsync(u => u.Id == userId); await SetUserSession(user, CommonHelper.IsMobile(_httpContextAccessor.HttpContext?.Request.Headers.UserAgent ?? "") ? LoginModeEnum.APP : LoginModeEnum.PC); } - - /// - /// 重置系统接口信息 - /// - [NonAction] - public async Task ResetSysApiInfo() - { - var id = SqlSugarConst.DefaultTenantId + 10000000000; - var apiList = new List(); - var apiDescriptionGroups = _apiProvider.ApiDescriptionGroups.Items; - foreach (ApiDescriptionGroup group in apiDescriptionGroups) - { - foreach (var action in group.Items) - { - // 控制器信息 - if (action.ActionDescriptor is not ControllerActionDescriptor actionDescriptor) continue; - var apiDescription = actionDescriptor.ControllerTypeInfo.GetCustomAttribute(true); - - // 路由 - var route = action.RelativePath!.Contains('{') ? action.RelativePath[..(action.RelativePath.IndexOf('{') - 1)] : action.RelativePath; // 去掉路由参数 - route = route[(route.IndexOf('/') + 1)..]; // 去掉路由前缀 - - // 获取分组名称和接口名称 - string groupName = null, displayText = null; - foreach (var attr in action.ActionDescriptor.EndpointMetadata) - { - switch (attr) - { - case ApiDescriptionSettingsAttribute settings: - if (!string.IsNullOrWhiteSpace(settings.GroupName)) groupName = settings.GroupName; - break; - - case DisplayNameAttribute displayName: - if (!string.IsNullOrWhiteSpace(displayName.DisplayName)) displayText = displayName.DisplayName; - break; - } - } - - apiList.Add(new SysApiInfo - { - Id = id++, - Route = route, - HttpMethod = action.HttpMethod, - Order = apiDescription?.Order ?? 0, - Action = actionDescriptor.ActionName, - Name = actionDescriptor.ControllerName, - GroupName = groupName ?? group.GroupName, - IsAppApi = actionDescriptor.ControllerTypeInfo.GetCustomAttribute(true) != null, - Desc = displayText ?? (string.IsNullOrWhiteSpace(apiDescription?.Description) ? actionDescriptor.ControllerName : apiDescription?.Description), - }); - } - } - - await _sysUserRep.Context.Deleteable().ExecuteCommandAsync(); - await _sysUserRep.Context.Insertable(apiList).ExecuteCommandAsync(); - } } \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/Service/Common/Dto/ApiOutput.cs b/Admin.NET/Admin.NET.Core/Service/Common/Dto/ApiOutput.cs index 401b5a55..ca96aacf 100644 --- a/Admin.NET/Admin.NET.Core/Service/Common/Dto/ApiOutput.cs +++ b/Admin.NET/Admin.NET.Core/Service/Common/Dto/ApiOutput.cs @@ -12,14 +12,24 @@ namespace Admin.NET.Core.Service; public class ApiOutput { /// - /// 名称(组名、路由名) + /// 组名 + /// + public string GroupName { get; set; } + + /// + /// 控制器名称 /// public string Name { get; set; } /// /// 描述 /// - public string Text { get; set; } + public string Desc { get; set; } + + /// + /// 是否是移动端接口 + /// + public bool IsAppApi { get; set; } /// /// 路由 diff --git a/Admin.NET/Admin.NET.Core/Service/Common/SysCommonService.cs b/Admin.NET/Admin.NET.Core/Service/Common/SysCommonService.cs index 5650c010..4bcb8214 100644 --- a/Admin.NET/Admin.NET.Core/Service/Common/SysCommonService.cs +++ b/Admin.NET/Admin.NET.Core/Service/Common/SysCommonService.cs @@ -103,7 +103,7 @@ public class SysCommonService : IDynamicApiController, ITransient var apiOuput = new ApiOutput { Name = "", - Text = string.IsNullOrWhiteSpace(group.GroupName) ? "系统接口" : group.GroupName, + Desc = string.IsNullOrWhiteSpace(group.GroupName) ? "系统接口" : group.GroupName, Route = "", }; // 获取分组的所有接口 @@ -134,7 +134,7 @@ public class SysCommonService : IDynamicApiController, ITransient apiOuput.Children.Add(new ApiOutput { Name = controllerName, - Text = string.IsNullOrWhiteSpace(controllerText) ? controllerName : controllerText, + Desc = string.IsNullOrWhiteSpace(controllerText) ? controllerName : controllerText, Route = "", Order = apiDescription?.Order ?? 0, }); @@ -149,7 +149,7 @@ public class SysCommonService : IDynamicApiController, ITransient apiController.Children.Add(new ApiOutput { Name = "", - Text = apiText, + Desc = apiText, Route = route, Action = actionName, HttpMethod = action.HttpMethod, @@ -172,16 +172,8 @@ public class SysCommonService : IDynamicApiController, ITransient [DisplayName("获取所有移动端接口")] public List GetAppApiList() { - List apiList = []; - var queue = new Queue(GetApiList()); - var item = queue.Dequeue(); - while (item != null) - { - if (item.Children is { Count: > 0 }) queue.EnqueueRange(item.Children); - else apiList.Add(item.Route); - item = queue.Count > 0 ? queue.Dequeue() : null; - } - return apiList; + var allApi = App.GetService().GetSysAllApiInfoList(); + return allApi.Where(u => u.IsAppApi).Select(u => u.Route).ToList(); } /// @@ -212,7 +204,7 @@ public class SysCommonService : IDynamicApiController, ITransient { var value = item.HttpMethod.Equals("get", StringComparison.CurrentCultureIgnoreCase) ? "params" : "data"; - stringBuilder.Append($@"// {item.Text}"); + stringBuilder.Append($@"// {item.Desc}"); stringBuilder.AppendLine(); stringBuilder.Append($@"export const {item.Action}Api = ({value}) => http.{item.HttpMethod.ToLower()}('/{defaultRoutePrefix}/{item.Route}', {value})"); stringBuilder.AppendLine(); diff --git a/Admin.NET/Admin.NET.Core/Service/User/UserManager.cs b/Admin.NET/Admin.NET.Core/Service/User/UserManager.cs index a0fd26c9..ac57e946 100644 --- a/Admin.NET/Admin.NET.Core/Service/User/UserManager.cs +++ b/Admin.NET/Admin.NET.Core/Service/User/UserManager.cs @@ -126,9 +126,9 @@ public class UserManager( public override string OpenId => Session?.OpenId; /// - /// 最大数据范围权限 + /// 数据范围权限列表 /// - public override DataScopeEnum? MaxDataScope => Session?.MaxDataScope; + public override List DataScopeList => Session?.DataScopeList; /// /// 角色Id集 diff --git a/Admin.NET/Admin.NET.Core/Service/User/UserSessionDao.cs b/Admin.NET/Admin.NET.Core/Service/User/UserSessionDao.cs index 2785bfc4..46304e05 100644 --- a/Admin.NET/Admin.NET.Core/Service/User/UserSessionDao.cs +++ b/Admin.NET/Admin.NET.Core/Service/User/UserSessionDao.cs @@ -67,10 +67,15 @@ public class UserSessionDao [Newtonsoft.Json.JsonIgnore] public bool SysAdmin => AccountType == AccountTypeEnum.SysAdmin; + /// + /// 数据范围权限列表 + /// + public virtual List DataScopeList { get; set; } + /// /// 最大数据范围权限 /// - public virtual DataScopeEnum? MaxDataScope { get; set; } + public DataScopeEnum MaxDataScope => DataScopeList.Any(u => u == DataScopeEnum.All) ? DataScopeEnum.All : DataScopeList.Any(u => u == DataScopeEnum.Define) ? DataScopeEnum.Define : DataScopeList.Min(); /// /// 组织机构Id diff --git a/Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarFilter.cs b/Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarFilter.cs index a4393d7a..b92ee900 100644 --- a/Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarFilter.cs +++ b/Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarFilter.cs @@ -116,8 +116,8 @@ public static class SqlSugarFilter var session = LazyHelper.GetService().Value.GetSessionOrRefresh(userId); if (session == null) return (int)DataScopeEnum.Self; - // 获取用户最大数据范围---仅本人数据 - maxDataScope = (int)session.MaxDataScope!; + // 获取用户最大数据范围--- 全部数据 -> 自定义 + maxDataScope = (int)session.MaxDataScope; if (maxDataScope != (int)DataScopeEnum.Self) return maxDataScope; // 配置用户数据范围缓存