diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/BootstrapAdmin.DataAccess.PetaPoco.csproj b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/BootstrapAdmin.DataAccess.PetaPoco.csproj index 77e2b810..36bc7d60 100644 --- a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/BootstrapAdmin.DataAccess.PetaPoco.csproj +++ b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/BootstrapAdmin.DataAccess.PetaPoco.csproj @@ -8,6 +8,7 @@ + diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/DictService.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/DictService.cs index 0d7caf36..41922bfd 100644 --- a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/DictService.cs +++ b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/DictService.cs @@ -1,4 +1,5 @@ -using BootstrapAdmin.DataAccess.Models; +using BootstrapAdmin.Caching; +using BootstrapAdmin.DataAccess.Models; using BootstrapAdmin.Web.Core; using BootstrapBlazor.Components; using Longbow.Security.Cryptography; @@ -9,6 +10,8 @@ namespace BootstrapAdmin.DataAccess.PetaPoco.Services; class DictService : IDict { + private const string DictServiceCacheKey = "DictService-GetAll"; + private IDatabase Database { get; } private string AppId { get; set; } @@ -24,7 +27,7 @@ class DictService : IDict AppId = configuration.GetValue("AppId", "BA"); } - public List GetAll() => Database.Fetch(); + public List GetAll() => CacheManager.GetOrAdd(DictServiceCacheKey, entry => Database.Fetch()); public Dictionary GetApps() { @@ -168,7 +171,16 @@ class DictService : IDict return ret; } - private bool SaveDict(Dict dict) => Database.Update("set Code = @Code where Category = @Category and Name = @Name", dict) == 1; + private bool SaveDict(Dict dict) + { + var ret = Database.Update("set Code = @Code where Category = @Category and Name = @Name", dict) == 1; + if (ret) + { + // 更新缓存 + CacheManager.Clear(DictServiceCacheKey); + } + return ret; + } public bool SaveLogin(string login) => SaveDict(new Dict { Category = "网站设置", Name = "登录界面", Code = login }); diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/NavigationService.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/NavigationService.cs index b0989a9a..820d1d17 100644 --- a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/NavigationService.cs +++ b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/NavigationService.cs @@ -1,4 +1,5 @@ -using BootstrapAdmin.DataAccess.Models; +using BootstrapAdmin.Caching; +using BootstrapAdmin.DataAccess.Models; using BootstrapAdmin.Web.Core; using PetaPoco; @@ -24,8 +25,11 @@ class NavigationService : INavigation /// 未层次化的菜单集合 public List GetAllMenus(string userName) { - var order = Database.Provider.EscapeSqlIdentifier("Order"); - return Database.Fetch($"select n.ID, n.ParentId, n.Name, n.{order}, n.Icon, n.Url, n.Category, n.Target, n.IsResource, n.Application, ln.Name as ParentName from Navigations n inner join Dicts d on n.Category = d.Code and d.Category = @Category and d.Define = @Define left join Navigations ln on n.ParentId = ln.ID inner join (select nr.NavigationID from Users u inner join UserRole ur on ur.UserID = u.ID inner join NavigationRole nr on nr.RoleID = ur.RoleID where u.UserName = @UserName union select nr.NavigationID from Users u inner join UserGroup ug on u.ID = ug.UserID inner join RoleGroup rg on rg.GroupID = ug.GroupID inner join NavigationRole nr on nr.RoleID = rg.RoleID where u.UserName = @UserName union select n.ID from Navigations n where EXISTS (select UserName from Users u inner join UserRole ur on u.ID = ur.UserID inner join Roles r on ur.RoleID = r.ID where u.UserName = @UserName and r.RoleName = @RoleName)) nav on n.ID = nav.NavigationID ORDER BY n.Application, n.{order}", new { UserName = userName, Category = "菜单", RoleName = "Administrators", Define = EnumDictDefine.System }); + return CacheManager.GetOrAdd($"{nameof(NavigationService)}-{nameof(GetAllMenus)}-{userName}", entry => + { + var order = Database.Provider.EscapeSqlIdentifier("Order"); + return Database.Fetch($"select n.ID, n.ParentId, n.Name, n.{order}, n.Icon, n.Url, n.Category, n.Target, n.IsResource, n.Application, ln.Name as ParentName from Navigations n inner join Dicts d on n.Category = d.Code and d.Category = @Category and d.Define = @Define left join Navigations ln on n.ParentId = ln.ID inner join (select nr.NavigationID from Users u inner join UserRole ur on ur.UserID = u.ID inner join NavigationRole nr on nr.RoleID = ur.RoleID where u.UserName = @UserName union select nr.NavigationID from Users u inner join UserGroup ug on u.ID = ug.UserID inner join RoleGroup rg on rg.GroupID = ug.GroupID inner join NavigationRole nr on nr.RoleID = rg.RoleID where u.UserName = @UserName union select n.ID from Navigations n where EXISTS (select UserName from Users u inner join UserRole ur on u.ID = ur.UserID inner join Roles r on ur.RoleID = r.ID where u.UserName = @UserName and r.RoleName = @RoleName)) nav on n.ID = nav.NavigationID ORDER BY n.Application, n.{order}", new { UserName = userName, Category = "菜单", RoleName = "Administrators", Define = EnumDictDefine.System }); + }); } /// @@ -50,7 +54,10 @@ class NavigationService : INavigation Database.Execute("delete from NavigationRole where RoleID = @0", roleId); Database.InsertBatch("NavigationRole", menuIds.Select(g => new { NavigationID = g, RoleID = roleId })); Database.CompleteTransaction(); + + // 通知缓存更新 ret = true; + CacheManager.Clear($"{nameof(NavigationService)}-{nameof(GetAllMenus)}-*"); } catch (Exception) { diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/TokenManager.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/TokenManager.cs new file mode 100644 index 00000000..e803e8c7 --- /dev/null +++ b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/TokenManager.cs @@ -0,0 +1,26 @@ +using BootstrapAdmin.DataAccess.PetaPoco.Services; +using Microsoft.Extensions.Primitives; + +namespace BootstrapAdmin.Caching; + +/// +/// +/// +public static class TokenManager +{ + /// + /// + /// + /// + /// + public static IChangeToken GetOrAdd(string key) + { + IChangeToken? token = null; + if (key.StartsWith($"{nameof(NavigationService)}-")) + { + // 菜单需要更新 + //token = new CompositeChangeToken(); + } + return token; + } +} diff --git a/src/blazor/admin/BootstrapAdmin.Web/BootstrapAdmin.db b/src/blazor/admin/BootstrapAdmin.Web/BootstrapAdmin.db index 86d51b25..bc2f736f 100644 Binary files a/src/blazor/admin/BootstrapAdmin.Web/BootstrapAdmin.db and b/src/blazor/admin/BootstrapAdmin.Web/BootstrapAdmin.db differ diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Healths.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Healths.razor.cs index b3b8484e..9ac0f085 100644 --- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Healths.razor.cs +++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Healths.razor.cs @@ -35,7 +35,7 @@ public partial class Healths [Inject] [NotNull] - private BootstrapBlazor.Web.Core.ICacheManager? CacheManager { get; set; } + private BootstrapAdmin.Caching.ICacheManager? CacheManager { get; set; } [NotNull] private HttpClient? Client { get; set; }