From e9851f4b7c54bbe9e2d967cabf6d3e4e3eeafe5b Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Wed, 3 Nov 2021 21:49:10 +0800 Subject: [PATCH] added UI navigation custom module. --- aspnet-core/LINGYUN.MicroService.All.sln | 17 + aspnet-core/LINGYUN.MicroService.Platform.sln | 17 + .../LINGYUN.Abp.UI.Navigation.csproj | 13 + .../Abp/UI/Navigation/AbpNavigationOptions.cs | 14 + .../UI/Navigation/AbpUINavigationModule.cs | 38 + .../Abp/UI/Navigation/ApplicationMenu.cs | 113 ++ .../Abp/UI/Navigation/ApplicationMenuList.cs | 45 + .../Abp/UI/Navigation/IHasMenuItems.cs | 10 + .../UI/Navigation/INavigationDataSeeder.cs | 19 + .../INavigationDefinitionContext.cs | 7 + .../INavigationDefinitionManager.cs | 9 + .../INavigationDefinitionProvider.cs | 7 + .../Abp/UI/Navigation/INavigationProvider.cs | 10 + .../NavigationDataSeedContributor.cs | 38 + .../Abp/UI/Navigation/NavigationDefinition.cs | 11 + .../Navigation/NavigationDefinitionContext.cs | 28 + .../Navigation/NavigationDefinitionManager.cs | 54 + .../NavigationDefinitionProvider.cs | 12 + .../Abp/UI/Navigation/NavigationProvider.cs | 30 + .../UI/Navigation/NullNavigationDataSeeder.cs | 18 + .../LINGYUN.Abp.UI.Navigation/README.md | 55 + ...GYUN.Abp.UI.Navigation.VueVbenAdmin.csproj | 17 + .../AbpUINavigationVueVbenAdminDataSeeder.cs | 399 ++++++ .../AbpUINavigationVueVbenAdminModule.cs | 12 + ...ueVbenAdminNavigationDefinitionProvider.cs | 353 ++++++ .../AbpUINavigationVueVbenAdminOptions.cs | 15 + .../README.md | 21 + .../AppPlatformHttpApiHostModule.cs | 2 + .../ElementAdminDataSeedContributor.cs | 962 --------------- .../VbenAdminDataSeedContributor.cs | 1089 ----------------- .../LINGYUN.Platform.HttpApi.Host.csproj | 1 + 31 files changed, 1385 insertions(+), 2051 deletions(-) create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN.Abp.UI.Navigation.csproj create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/AbpNavigationOptions.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/AbpUINavigationModule.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/ApplicationMenu.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/ApplicationMenuList.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/IHasMenuItems.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDataSeeder.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDefinitionContext.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDefinitionManager.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDefinitionProvider.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationProvider.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDataSeedContributor.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinition.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinitionContext.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinitionManager.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinitionProvider.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationProvider.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NullNavigationDataSeeder.cs create mode 100644 aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/README.md create mode 100644 aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN.Abp.UI.Navigation.VueVbenAdmin.csproj create mode 100644 aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminDataSeeder.cs create mode 100644 aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminModule.cs create mode 100644 aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminNavigationDefinitionProvider.cs create mode 100644 aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminOptions.cs create mode 100644 aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/README.md delete mode 100644 aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/DataSeeder/ElementAdminDataSeedContributor.cs delete mode 100644 aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/DataSeeder/VbenAdminDataSeedContributor.cs diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln index bec216761..4837ff981 100644 --- a/aspnet-core/LINGYUN.MicroService.All.sln +++ b/aspnet-core/LINGYUN.MicroService.All.sln @@ -353,6 +353,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Serilog.Enriche EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Data.DbMigrator", "modules\common\LINGYUN.Abp.Data.DbMigrator\LINGYUN.Abp.Data.DbMigrator.csproj", "{91D9F43A-BFD9-47CA-A6AD-430D1663EFF3}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "navigation", "navigation", "{7D02D803-F9A9-492C-9B5E-454E4B258466}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.UI.Navigation", "modules\navigation\LINGYUN.Abp.UI.Navigation\LINGYUN.Abp.UI.Navigation.csproj", "{FD04A084-BB8A-4733-B9C5-FACF40342A8A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.UI.Navigation.VueVbenAdmin", "modules\platform\LINGYUN.Abp.UI.Navigation.VueVbenAdmin\LINGYUN.Abp.UI.Navigation.VueVbenAdmin.csproj", "{67A76560-D39F-4D49-B858-B476E1DFE37B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -923,6 +929,14 @@ Global {91D9F43A-BFD9-47CA-A6AD-430D1663EFF3}.Debug|Any CPU.Build.0 = Debug|Any CPU {91D9F43A-BFD9-47CA-A6AD-430D1663EFF3}.Release|Any CPU.ActiveCfg = Release|Any CPU {91D9F43A-BFD9-47CA-A6AD-430D1663EFF3}.Release|Any CPU.Build.0 = Release|Any CPU + {FD04A084-BB8A-4733-B9C5-FACF40342A8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FD04A084-BB8A-4733-B9C5-FACF40342A8A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FD04A084-BB8A-4733-B9C5-FACF40342A8A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FD04A084-BB8A-4733-B9C5-FACF40342A8A}.Release|Any CPU.Build.0 = Release|Any CPU + {67A76560-D39F-4D49-B858-B476E1DFE37B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {67A76560-D39F-4D49-B858-B476E1DFE37B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {67A76560-D39F-4D49-B858-B476E1DFE37B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {67A76560-D39F-4D49-B858-B476E1DFE37B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1097,6 +1111,9 @@ Global {F71A0D28-397D-4094-B1C2-7925E1310676} = {67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4} {CEAF0044-28D3-4585-B69D-D65FF6D4745E} = {6FC0578B-CDF1-43AD-9F7E-4AA7E4720A02} {91D9F43A-BFD9-47CA-A6AD-430D1663EFF3} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} + {7D02D803-F9A9-492C-9B5E-454E4B258466} = {C5CAD011-DF84-4914-939C-0C029DCEF26F} + {FD04A084-BB8A-4733-B9C5-FACF40342A8A} = {7D02D803-F9A9-492C-9B5E-454E4B258466} + {67A76560-D39F-4D49-B858-B476E1DFE37B} = {F4923692-D343-4318-AECA-96F580B1A563} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} diff --git a/aspnet-core/LINGYUN.MicroService.Platform.sln b/aspnet-core/LINGYUN.MicroService.Platform.sln index 4ceb03051..31ed1fd60 100644 --- a/aspnet-core/LINGYUN.MicroService.Platform.sln +++ b/aspnet-core/LINGYUN.MicroService.Platform.sln @@ -86,6 +86,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Serilog.Enriche EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Data.DbMigrator", "modules\common\LINGYUN.Abp.Data.DbMigrator\LINGYUN.Abp.Data.DbMigrator.csproj", "{FA49E154-CD90-4E11-8216-3EF545C32294}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.UI.Navigation.VueVbenAdmin", "modules\platform\LINGYUN.Abp.UI.Navigation.VueVbenAdmin\LINGYUN.Abp.UI.Navigation.VueVbenAdmin.csproj", "{2A69A38F-E98A-490D-BEAE-1BBBD87121DD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "navigation", "navigation", "{D61721B8-B0F7-4C3D-AD1B-44FBE81DFA79}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.UI.Navigation", "modules\navigation\LINGYUN.Abp.UI.Navigation\LINGYUN.Abp.UI.Navigation.csproj", "{BE9131C0-7DD4-4032-A5F7-4B9D76EC16CF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -212,6 +218,14 @@ Global {FA49E154-CD90-4E11-8216-3EF545C32294}.Debug|Any CPU.Build.0 = Debug|Any CPU {FA49E154-CD90-4E11-8216-3EF545C32294}.Release|Any CPU.ActiveCfg = Release|Any CPU {FA49E154-CD90-4E11-8216-3EF545C32294}.Release|Any CPU.Build.0 = Release|Any CPU + {2A69A38F-E98A-490D-BEAE-1BBBD87121DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A69A38F-E98A-490D-BEAE-1BBBD87121DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A69A38F-E98A-490D-BEAE-1BBBD87121DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A69A38F-E98A-490D-BEAE-1BBBD87121DD}.Release|Any CPU.Build.0 = Release|Any CPU + {BE9131C0-7DD4-4032-A5F7-4B9D76EC16CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE9131C0-7DD4-4032-A5F7-4B9D76EC16CF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE9131C0-7DD4-4032-A5F7-4B9D76EC16CF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE9131C0-7DD4-4032-A5F7-4B9D76EC16CF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -254,6 +268,9 @@ Global {F90823E2-53DC-4751-BCCD-6C11B3899592} = {20E8BAE5-C13E-4F86-9EB0-EF24F50442B5} {6C048526-5A14-4835-B8BA-1C0C6E887225} = {D845545B-57C4-43A1-985B-23C372340CD6} {FA49E154-CD90-4E11-8216-3EF545C32294} = {265D5E44-682B-49BC-984A-BDD8CA45E60E} + {2A69A38F-E98A-490D-BEAE-1BBBD87121DD} = {4096EC6A-EEAD-4E5B-B087-393D7A4E5874} + {D61721B8-B0F7-4C3D-AD1B-44FBE81DFA79} = {15BDA03E-DE8E-46E4-96A8-CA3F2872E812} + {BE9131C0-7DD4-4032-A5F7-4B9D76EC16CF} = {D61721B8-B0F7-4C3D-AD1B-44FBE81DFA79} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {03D3B66F-8926-4C00-B7AB-A21761EC859E} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN.Abp.UI.Navigation.csproj b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN.Abp.UI.Navigation.csproj new file mode 100644 index 000000000..d259062ac --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN.Abp.UI.Navigation.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.0 + + + + + + + + + diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/AbpNavigationOptions.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/AbpNavigationOptions.cs new file mode 100644 index 000000000..cac598435 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/AbpNavigationOptions.cs @@ -0,0 +1,14 @@ +using Volo.Abp.Collections; + +namespace LINGYUN.Abp.UI.Navigation +{ + public class AbpNavigationOptions + { + public ITypeList DefinitionProviders { get; } + + public AbpNavigationOptions() + { + DefinitionProviders = new TypeList(); + } + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/AbpUINavigationModule.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/AbpUINavigationModule.cs new file mode 100644 index 000000000..1a00ad813 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/AbpUINavigationModule.cs @@ -0,0 +1,38 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy; +using Volo.Abp.ObjectExtending; + +namespace LINGYUN.Abp.UI.Navigation +{ + [DependsOn( + typeof(AbpMultiTenancyModule), + typeof(AbpObjectExtendingModule))] + public class AbpUINavigationModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + AutoAddDefinitionProviders(context.Services); + } + + private static void AutoAddDefinitionProviders(IServiceCollection services) + { + var definitionProviders = new List(); + + services.OnRegistred(context => + { + if (typeof(INavigationDefinitionProvider).IsAssignableFrom(context.ImplementationType)) + { + definitionProviders.Add(context.ImplementationType); + } + }); + + services.Configure(options => + { + options.DefinitionProviders.AddIfNotContains(definitionProviders); + }); + } + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/ApplicationMenu.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/ApplicationMenu.cs new file mode 100644 index 000000000..4d2d5c088 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/ApplicationMenu.cs @@ -0,0 +1,113 @@ +using JetBrains.Annotations; +using System; +using System.Collections.Generic; +using Volo.Abp; +using Volo.Abp.Data; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.UI.Navigation +{ + public class ApplicationMenu : IHasMenuItems, IHasExtraProperties + { + public const int DefaultOrder = 1000; + /// + /// 名称 + /// + [NotNull] + public string Name { get; } + /// + /// 显示名称 + /// + [NotNull] + public string DisplayName { get; } + /// + /// 说明 + /// + [CanBeNull] + public string Description { get; } + /// + /// 路径 + /// + [NotNull] + public string Url { get; } + /// + /// 组件 + /// + [CanBeNull] + public string Component { get; } + /// + /// 重定向 + /// + [CanBeNull] + public string Redirect { get; } + /// + /// 图标 + /// + [CanBeNull] + public string Icon { get; set; } + /// + /// 排序 + /// + public int Order { get; set; } + /// + /// 是否禁用 + /// + public bool IsDisabled { get; set; } + /// + /// 是否可视 + /// + public bool IsVisible { get; set; } + + [NotNull] + public ApplicationMenuList Items { get; } + + public bool IsLeaf => Items.IsNullOrEmpty(); + + [NotNull] + public ExtraPropertyDictionary ExtraProperties { get; } + + public MultiTenancySides MultiTenancySides { get; } + + public ApplicationMenu( + [NotNull] string name, + [NotNull] string displayName, + [NotNull] string url, + [CanBeNull] string component, + string description = null, + string icon = null, + string redirect = null, + int order = DefaultOrder, + MultiTenancySides multiTenancySides = MultiTenancySides.Both) + { + Check.NotNullOrWhiteSpace(name, nameof(name)); + Check.NotNullOrWhiteSpace(displayName, nameof(displayName)); + + Check.NotNullOrWhiteSpace(url, nameof(url)); + + Name = name; + DisplayName = displayName; + Url = url; + Component = component; + Description = description; + Icon = icon; + Redirect = redirect ?? ""; + Order = order; + MultiTenancySides = multiTenancySides; + + Items = new ApplicationMenuList(); + ExtraProperties = new ExtraPropertyDictionary(); + this.SetDefaultsForExtraProperties(); + } + + public ApplicationMenu AddItem([NotNull] ApplicationMenu menuItem) + { + Items.Add(menuItem); + return menuItem; + } + + public override string ToString() + { + return $"[ApplicationMenu] Name = {Name}"; + } + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/ApplicationMenuList.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/ApplicationMenuList.cs new file mode 100644 index 000000000..48e22e309 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/ApplicationMenuList.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace LINGYUN.Abp.UI.Navigation +{ + public class ApplicationMenuList : List + { + public ApplicationMenuList() + { + + } + + public ApplicationMenuList(int capacity) + : base(capacity) + { + + } + + public ApplicationMenuList(IEnumerable collection) + : base(collection) + { + + } + + public void Normalize() + { + RemoveEmptyItems(); + Order(); + } + + private void RemoveEmptyItems() + { + RemoveAll(item => item.IsLeaf && item.Url.IsNullOrEmpty()); + } + + private void Order() + { + //TODO: Is there any way that is more performant? + var orderedItems = this.OrderBy(item => item.Order).ToArray(); + Clear(); + AddRange(orderedItems); + } + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/IHasMenuItems.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/IHasMenuItems.cs new file mode 100644 index 000000000..62d45878a --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/IHasMenuItems.cs @@ -0,0 +1,10 @@ +namespace LINGYUN.Abp.UI.Navigation +{ + public interface IHasMenuItems + { + /// + /// Menu items. + /// + ApplicationMenuList Items { get; } + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDataSeeder.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDataSeeder.cs new file mode 100644 index 000000000..67320c39e --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDataSeeder.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.UI.Navigation +{ + public interface INavigationDataSeeder + { + /// + /// + /// + /// 菜单列表 + /// 让用户自行决定是否过滤菜单 + /// + Task SeedAsync( + IReadOnlyCollection menus, + MultiTenancySides multiTenancySides = MultiTenancySides.Both); + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDefinitionContext.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDefinitionContext.cs new file mode 100644 index 000000000..493b9fa29 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDefinitionContext.cs @@ -0,0 +1,7 @@ +namespace LINGYUN.Abp.UI.Navigation +{ + public interface INavigationDefinitionContext + { + void Add(params NavigationDefinition[] definitions); + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDefinitionManager.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDefinitionManager.cs new file mode 100644 index 000000000..653321a63 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDefinitionManager.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace LINGYUN.Abp.UI.Navigation +{ + public interface INavigationDefinitionManager + { + IReadOnlyList GetAll(); + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDefinitionProvider.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDefinitionProvider.cs new file mode 100644 index 000000000..1c101b040 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationDefinitionProvider.cs @@ -0,0 +1,7 @@ +namespace LINGYUN.Abp.UI.Navigation +{ + public interface INavigationDefinitionProvider + { + void Define(INavigationDefinitionContext context); + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationProvider.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationProvider.cs new file mode 100644 index 000000000..6fd3ec37d --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/INavigationProvider.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.UI.Navigation +{ + public interface INavigationProvider + { + Task> GetAllAsync(); + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDataSeedContributor.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDataSeedContributor.cs new file mode 100644 index 000000000..d0eee9158 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDataSeedContributor.cs @@ -0,0 +1,38 @@ +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.UI.Navigation +{ + public class NavigationDataSeedContributor : IDataSeedContributor, ITransientDependency + { + private readonly ICurrentTenant _currentTenant; + private readonly INavigationProvider _navigationProvider; + private readonly INavigationDataSeeder _navigationDataSeeder; + + public NavigationDataSeedContributor( + ICurrentTenant currentTenant, + INavigationProvider navigationProvider, + INavigationDataSeeder navigationDataSeeder) + { + _currentTenant = currentTenant; + _navigationProvider = navigationProvider; + _navigationDataSeeder = navigationDataSeeder; + } + + public virtual async Task SeedAsync(DataSeedContext context) + { + using(_currentTenant.Change(context.TenantId)) + { + var multiTenancySides = _currentTenant.Id.HasValue + ? MultiTenancySides.Tenant + : MultiTenancySides.Host; + + var menus = await _navigationProvider.GetAllAsync(); + + await _navigationDataSeeder.SeedAsync(menus, multiTenancySides); + } + } + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinition.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinition.cs new file mode 100644 index 000000000..b4456e285 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinition.cs @@ -0,0 +1,11 @@ +namespace LINGYUN.Abp.UI.Navigation +{ + public class NavigationDefinition + { + public ApplicationMenu Menu { get; } + public NavigationDefinition(ApplicationMenu menu) + { + Menu = menu; + } + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinitionContext.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinitionContext.cs new file mode 100644 index 000000000..191666961 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinitionContext.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; + +namespace LINGYUN.Abp.UI.Navigation +{ + public class NavigationDefinitionContext : INavigationDefinitionContext + { + protected List Navigations { get; } + public NavigationDefinitionContext(List navigations) + { + Navigations = navigations; + } + public virtual IReadOnlyList GetAll() + { + return Navigations.ToImmutableList(); + } + + public virtual void Add(params NavigationDefinition[] definitions) + { + if (definitions.IsNullOrEmpty()) + { + return; + } + Navigations.AddRange(definitions); + } + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinitionManager.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinitionManager.cs new file mode 100644 index 000000000..a4d73c1ed --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinitionManager.cs @@ -0,0 +1,54 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.UI.Navigation +{ + public class NavigationDefinitionManager : INavigationDefinitionManager, ISingletonDependency + { + protected Lazy> NavigationDefinitions { get; } + + protected AbpNavigationOptions Options { get; } + + protected IServiceProvider ServiceProvider { get; } + + public NavigationDefinitionManager( + IOptions options, + IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + Options = options.Value; + + NavigationDefinitions = new Lazy>(CreateSettingDefinitions, true); + } + + public virtual IReadOnlyList GetAll() + { + return NavigationDefinitions.Value.ToImmutableList(); + } + + protected virtual IList CreateSettingDefinitions() + { + var settings = new List(); + + using (var scope = ServiceProvider.CreateScope()) + { + var providers = Options + .DefinitionProviders + .Select(p => scope.ServiceProvider.GetRequiredService(p) as INavigationDefinitionProvider) + .ToList(); + + foreach (var provider in providers) + { + provider.Define(new NavigationDefinitionContext(settings)); + } + } + + return settings; + } + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinitionProvider.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinitionProvider.cs new file mode 100644 index 000000000..d5179da5a --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationDefinitionProvider.cs @@ -0,0 +1,12 @@ +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.UI.Navigation +{ + public abstract class NavigationDefinitionProvider : INavigationDefinitionProvider, ITransientDependency + { + protected NavigationDefinitionProvider() + { + } + public abstract void Define(INavigationDefinitionContext context); + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationProvider.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationProvider.cs new file mode 100644 index 000000000..2c9d3dbd2 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NavigationProvider.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.UI.Navigation +{ + public class NavigationProvider : INavigationProvider, ITransientDependency + { + protected INavigationDefinitionManager NavigationDefinitionManager { get; } + public NavigationProvider( + INavigationDefinitionManager navigationDefinitionManager) + { + NavigationDefinitionManager = navigationDefinitionManager; + } + public Task> GetAllAsync() + { + var navigations = new List(); + var navigationDefineitions = NavigationDefinitionManager.GetAll(); + foreach (var navigationDefineition in navigationDefineitions) + { + navigations.Add(navigationDefineition.Menu); + } + + IReadOnlyCollection menus = navigations.ToImmutableList(); + + return Task.FromResult(menus); + } + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NullNavigationDataSeeder.cs b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NullNavigationDataSeeder.cs new file mode 100644 index 000000000..ba7540997 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/LINGYUN/Abp/UI/Navigation/NullNavigationDataSeeder.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.UI.Navigation +{ + [Dependency(TryRegister = true)] + public class NullNavigationDataSeeder : INavigationDataSeeder, ISingletonDependency + { + public Task SeedAsync( + IReadOnlyCollection menus, + MultiTenancySides multiTenancySides = MultiTenancySides.Both) + { + return Task.CompletedTask; + } + } +} diff --git a/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/README.md b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/README.md new file mode 100644 index 000000000..18c68e1f8 --- /dev/null +++ b/aspnet-core/modules/navigation/LINGYUN.Abp.UI.Navigation/README.md @@ -0,0 +1,55 @@ +# LINGYUN.Abp.UI.Navigation + +菜单导航模块,提供可扩展自定义的菜单项 + +## 配置使用 + +应用初始化时扫描所有实现 **INavigationDefinitionProvider** 接口的用户定义菜单项 + +通过 **INavigationDataSeeder** 接口初始化菜单种子数据 + +**INavigationDataSeeder** 的实现交给具体的实现 + +```csharp +[DependsOn(typeof(AbpUINavigationModule))] +public class YouProjectModule : AbpModule +{ + // other +} +``` + +```csharp + +public class FakeNavigationDefinitionProvider : NavigationDefinitionProvider +{ + public override void Define(INavigationDefinitionContext context) + { + context.Add(GetNavigationDefinition()); + } + + private static NavigationDefinition GetNavigationDefinition() + { + var dashboard = new ApplicationMenu( + name: "Vben Dashboard", + displayName: "仪表盘", + url: "/dashboard", + component: "", + description: "仪表盘", + icon: "ion:grid-outline", + redirect: "/dashboard/analysis"); + + dashboard.AddItem( + new ApplicationMenu( + name: "Analysis", + displayName: "分析页", + url: "/dashboard/analysis", + component: "/dashboard/analysis/index", + description: "分析页")); + + return new NavigationDefinition(dashboard); + } +} + +``` + +## 其他 diff --git a/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN.Abp.UI.Navigation.VueVbenAdmin.csproj b/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN.Abp.UI.Navigation.VueVbenAdmin.csproj new file mode 100644 index 000000000..ec74698d6 --- /dev/null +++ b/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN.Abp.UI.Navigation.VueVbenAdmin.csproj @@ -0,0 +1,17 @@ + + + + netstandard2.0 + + + + + + + + + + + + + diff --git a/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminDataSeeder.cs b/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminDataSeeder.cs new file mode 100644 index 000000000..9c0709620 --- /dev/null +++ b/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminDataSeeder.cs @@ -0,0 +1,399 @@ +using LINGYUN.Platform.Datas; +using LINGYUN.Platform.Layouts; +using LINGYUN.Platform.Menus; +using LINGYUN.Platform.Routes; +using LINGYUN.Platform.Utils; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; +using ValueType = LINGYUN.Platform.Datas.ValueType; + +namespace LINGYUN.Abp.UI.Navigation.VueVbenAdmin +{ + public class AbpUINavigationVueVbenAdminDataSeeder : INavigationDataSeeder, ITransientDependency + { + private static int _lastCodeNumber = 0; + protected ICurrentTenant CurrentTenant { get; } + protected IGuidGenerator GuidGenerator { get; } + protected IRouteDataSeeder RouteDataSeeder { get; } + protected IDataDictionaryDataSeeder DataDictionaryDataSeeder { get; } + protected IMenuRepository MenuRepository { get; } + protected ILayoutRepository LayoutRepository { get; } + protected AbpUINavigationVueVbenAdminOptions Options { get; } + + public AbpUINavigationVueVbenAdminDataSeeder( + ICurrentTenant currentTenant, + IRouteDataSeeder routeDataSeeder, + IMenuRepository menuRepository, + ILayoutRepository layoutRepository, + IGuidGenerator guidGenerator, + IDataDictionaryDataSeeder dataDictionaryDataSeeder, + IOptions options) + { + CurrentTenant = currentTenant; + GuidGenerator = guidGenerator; + RouteDataSeeder = routeDataSeeder; + MenuRepository = menuRepository; + LayoutRepository = layoutRepository; + DataDictionaryDataSeeder = dataDictionaryDataSeeder; + + Options = options.Value; + } + + public virtual async Task SeedAsync( + IReadOnlyCollection menus, + MultiTenancySides multiTenancySides = MultiTenancySides.Both) + { + var uiDataItem = await SeedUIFrameworkDataAsync(CurrentTenant.Id); + + var layoutData = await SeedLayoutDataAsync(CurrentTenant.Id); + + var layout = await SeedDefaultLayoutAsync(layoutData, uiDataItem); + + var latMenu = await MenuRepository.GetLastMenuAsync(); + + if (int.TryParse(CodeNumberGenerator.GetLastCode(latMenu?.Code ?? "0"), out int _lastNumber)) + { + Interlocked.Exchange(ref _lastCodeNumber, _lastNumber); + } + + await SeedDefinitionMenusAsync(layout, layoutData, menus, multiTenancySides); + } + + private async Task SeedDefinitionMenusAsync( + Layout layout, + Data data, + IReadOnlyCollection menus, + MultiTenancySides multiTenancySides) + { + foreach (var menu in menus) + { + if (!menu.MultiTenancySides.HasFlag(multiTenancySides)) + { + continue; + } + + var menuMeta = new Dictionary() + { + { "title", menu.DisplayName }, + { "icon", menu.Icon ?? "" }, + { "hideTab", false }, + { "ignoreAuth", false }, + }; + menuMeta.AddIfNotContains(menu.ExtraProperties); + + var seedMenu = await SeedMenuAsync( + layout: layout, + data: data, + name: menu.Name, + path: menu.Url, + code: CodeNumberGenerator.CreateCode(GetNextCode()), + component: layout.Path, + displayName: menu.DisplayName, + redirect: "", + description: menu.Description, + parentId: null, + tenantId: layout.TenantId, + meta: menuMeta, + roles: new string[] { "admin" }); + + await SeedDefinitionMenuItemsAsync(layout, data, seedMenu, menu.Items, multiTenancySides); + } + } + + private async Task SeedDefinitionMenuItemsAsync( + Layout layout, + Data data, + Menu menu, + ApplicationMenuList items, + MultiTenancySides multiTenancySides) + { + int index = 1; + foreach (var item in items) + { + if (!item.MultiTenancySides.HasFlag(multiTenancySides)) + { + continue; + } + + var menuMeta = new Dictionary() + { + { "title", item.DisplayName }, + { "icon", item.Icon ?? "" }, + { "hideTab", false }, + { "ignoreAuth", false }, + }; + menuMeta.AddIfNotContains(item.ExtraProperties); + + var seedMenu = await SeedMenuAsync( + layout: layout, + data: data, + name: item.Name, + path: item.Url, + code: CodeNumberGenerator.AppendCode(menu.Code, CodeNumberGenerator.CreateCode(index)), + component: item.Component.IsNullOrWhiteSpace() ? layout.Path : item.Component, + displayName: item.DisplayName, + redirect: "", + description: item.Description, + parentId: menu.Id, + tenantId: menu.TenantId, + meta: menuMeta, + roles: new string[] { "admin" }); + + await SeedDefinitionMenuItemsAsync(layout, data, seedMenu, item.Items, multiTenancySides); + + index++; + } + } + + private async Task SeedMenuAsync( + Layout layout, + Data data, + string name, + string path, + string code, + string component, + string displayName, + string redirect = "", + string description = "", + Guid? parentId = null, + Guid? tenantId = null, + Dictionary meta = null, + string[] roles = null, + Guid[] users = null, + bool isPublic = false + ) + { + var menu = await RouteDataSeeder.SeedMenuAsync( + layout, + name, + path, + code, + component, + displayName, + redirect, + description, + parentId, + tenantId, + isPublic + ); + foreach (var item in data.Items) + { + menu.SetProperty(item.Name, item.DefaultValue); + } + if (meta != null) + { + foreach (var item in meta) + { + menu.SetProperty(item.Key, item.Value); + } + } + + if (roles != null) + { + foreach (var role in roles) + { + await RouteDataSeeder.SeedRoleMenuAsync(role, menu, tenantId); + } + } + + if (users != null) + { + foreach (var user in users) + { + await RouteDataSeeder.SeedUserMenuAsync(user, menu, tenantId); + } + } + + return menu; + } + + private async Task SeedUIFrameworkDataAsync(Guid? tenantId) + { + var data = await DataDictionaryDataSeeder + .SeedAsync( + "UI Framework", + CodeNumberGenerator.CreateCode(10), + "UI框架", + "UI Framework", + null, + tenantId, + true); + + data.AddItem( + GuidGenerator, + Options.UI, + Options.UI, + Options.UI, + ValueType.String, + Options.UI, + isStatic: true); + + return data.FindItem(Options.UI); + } + + private async Task SeedDefaultLayoutAsync(Data data, DataItem uiDataItem) + { + var layout = await RouteDataSeeder.SeedLayoutAsync( + Options.LayoutName, + Options.LayoutPath, // 路由层面已经处理好了,只需要传递LAYOUT可自动引用布局 + Options.LayoutName, + data.Id, + uiDataItem.Name, + "", + Options.LayoutName, + data.TenantId + ); + + return layout; + } + + private async Task SeedLayoutDataAsync(Guid? tenantId) + { + var data = await DataDictionaryDataSeeder + .SeedAsync( + Options.LayoutName, + CodeNumberGenerator.CreateCode(10), + "Vben Admin 布局约束", + "Vben Admin Layout Meta Dictionary", + null, + tenantId, + true); + + data.AddItem( + GuidGenerator, + "hideMenu", + "不在菜单显示", + "false", + ValueType.Boolean, + "当前路由不在菜单显示", + isStatic: true); + data.AddItem( + GuidGenerator, + "icon", + "图标", + "", + ValueType.String, + "图标,也是菜单图标", + isStatic: true); + data.AddItem( + GuidGenerator, + "currentActiveMenu", + "当前激活的菜单", + "", + ValueType.String, + "用于配置详情页时左侧激活的菜单路径", + isStatic: true); + data.AddItem( + GuidGenerator, + "ignoreKeepAlive", + "KeepAlive缓存", + "false", + ValueType.Boolean, + "是否忽略KeepAlive缓存", + isStatic: true); + data.AddItem( + GuidGenerator, + "frameSrc", + "IFrame地址", + "", + ValueType.String, + "内嵌iframe的地址", + isStatic: true); + data.AddItem( + GuidGenerator, + "transitionName", + "路由切换动画", + "", + ValueType.String, + "指定该路由切换的动画名", + isStatic: true); + data.AddItem( + GuidGenerator, + "roles", + "可以访问的角色", + "", + ValueType.Array, + "可以访问的角色,只在权限模式为Role的时候有效", + isStatic: true); + data.AddItem( + GuidGenerator, + "title", + "路由标题", + "", + ValueType.String, + "路由title 一般必填", + false, + isStatic: true); + data.AddItem( + GuidGenerator, + "carryParam", + "在tab页显示", + "false", + ValueType.Boolean, + "如果该路由会携带参数,且需要在tab页上面显示。则需要设置为true", + isStatic: true); + data.AddItem( + GuidGenerator, + "hideBreadcrumb", + "隐藏面包屑", + "false", + ValueType.Boolean, + "隐藏该路由在面包屑上面的显示", + isStatic: true); + data.AddItem( + GuidGenerator, + "ignoreAuth", + "忽略权限", + "false", + ValueType.Boolean, + "是否忽略权限,只在权限模式为Role的时候有效", + isStatic: true); + data.AddItem( + GuidGenerator, + "hideChildrenInMenu", + "隐藏所有子菜单", + "false", + ValueType.Boolean, + "隐藏所有子菜单", + isStatic: true); + data.AddItem( + GuidGenerator, + "hideTab", + "不在标签页显示", + "false", + ValueType.Boolean, + "当前路由不在标签页显示", + isStatic: true); + data.AddItem( + GuidGenerator, + "affix", + "固定标签页", + "false", + ValueType.Boolean, + "是否固定标签页", + isStatic: true); + data.AddItem( + GuidGenerator, + "frameFormat", + "格式化IFrame", + "false", + ValueType.Boolean, + "扩展的格式化frame,{token}: 在打开的iframe页面传递token请求头"); + + return data; + } + + private int GetNextCode() + { + Interlocked.Increment(ref _lastCodeNumber); + return _lastCodeNumber; + } + } +} diff --git a/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminModule.cs b/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminModule.cs new file mode 100644 index 000000000..aabff877d --- /dev/null +++ b/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminModule.cs @@ -0,0 +1,12 @@ +using LINGYUN.Platform; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.UI.Navigation.VueVbenAdmin +{ + [DependsOn( + typeof(AbpUINavigationModule), + typeof(PlatformDomainModule))] + public class AbpUINavigationVueVbenAdminModule : AbpModule + { + } +} diff --git a/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminNavigationDefinitionProvider.cs b/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminNavigationDefinitionProvider.cs new file mode 100644 index 000000000..5f668da12 --- /dev/null +++ b/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminNavigationDefinitionProvider.cs @@ -0,0 +1,353 @@ +using Volo.Abp.Data; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.UI.Navigation.VueVbenAdmin +{ + public class AbpUINavigationVueVbenAdminNavigationDefinitionProvider : NavigationDefinitionProvider + { + public override void Define(INavigationDefinitionContext context) + { + context.Add(GetDashboard()); + context.Add(GetManage()); + context.Add(GetSaas()); + context.Add(GetPlatform()); + context.Add(GetApiGateway()); + context.Add(GetLocalization()); + context.Add(GetOssManagement()); + } + + private static NavigationDefinition GetDashboard() + { + var dashboard = new ApplicationMenu( + name: "Vben Dashboard", + displayName: "仪表盘", + url: "/dashboard", + component: "", + description: "仪表盘", + icon: "ion:grid-outline", + redirect: "/dashboard/workbench"); + + dashboard.AddItem( + new ApplicationMenu( + name: "Analysis", + displayName: "分析页", + url: "/dashboard/analysis", + component: "/dashboard/analysis/index", + description: "分析页")); + dashboard.AddItem( + new ApplicationMenu( + name: "Workbench", + displayName: "工作台", + url: "/dashboard/workbench", + component: "/dashboard/workbench/index", + description: "工作台")); + + + return new NavigationDefinition(dashboard); + } + + private static NavigationDefinition GetManage() + { + var manage = new ApplicationMenu( + name: "Manage", + displayName: "管理", + url: "/manage", + component: "", + description: "管理", + icon: "ant-design:control-outlined"); + + var identity = manage.AddItem( + new ApplicationMenu( + name: "Identity", + displayName: "身份认证管理", + url: "/manage/identity", + component: "", + description: "身份认证管理")); + identity.AddItem( + new ApplicationMenu( + name: "User", + displayName: "用户", + url: "/manage/identity/user", + component: "/identity/user/index", + description: "用户")); + identity.AddItem( + new ApplicationMenu( + name: "Role", + displayName: "角色", + url: "/manage/identity/role", + component: "/identity/role/index", + description: "角色")); + identity.AddItem( + new ApplicationMenu( + name: "Claim", + displayName: "身份标识", + url: "/manage/identity/claim-types", + component: "/identity/claim-types/index", + description: "身份标识", + multiTenancySides: MultiTenancySides.Host)); + identity.AddItem( + new ApplicationMenu( + name: "OrganizationUnits", + displayName: "组织机构", + url: "/manage/identity/organization-units", + component: "/identity/organization-units/index", + description: "组织机构")); + identity.AddItem( + new ApplicationMenu( + name: "SecurityLogs", + displayName: "安全日志", + url: "/manage/identity/security-logs", + component: "/identity/security-logs/index", + description: "安全日志") + // 此路由需要依赖安全日志特性 + .SetProperty("requiredFeatures", "AbpAuditing.Logging.SecurityLog")); + + manage.AddItem(new ApplicationMenu( + name: "AuditLogs", + displayName: "审计日志", + url: "/manage/audit-logs", + component: "/auditing/index", + description: "审计日志") + // 此路由需要依赖审计日志特性 + .SetProperty("requiredFeatures", "AbpAuditing.Logging.AuditLog")); + + manage.AddItem(new ApplicationMenu( + name: "Settings", + displayName: "设置", + url: "/manage/settings", + component: "/sys/settings/index", + description: "设置") + // 此路由需要依赖设置管理特性 + .SetProperty("requiredFeatures", "SettingManagement.Enable")); + + var identityServer = manage.AddItem( + new ApplicationMenu( + name: "IdentityServer", + displayName: "身份认证服务器", + url: "/manage/identity-server", + component: "", + description: "身份认证服务器", + multiTenancySides: MultiTenancySides.Host)); + identityServer.AddItem( + new ApplicationMenu( + name: "Clients", + displayName: "客户端", + url: "/manage/identity-server/clients", + component: "/identity-server/clients/index", + description: "客户端", + multiTenancySides: MultiTenancySides.Host)); + identityServer.AddItem( + new ApplicationMenu( + name: "ApiResources", + displayName: "Api 资源", + url: "/manage/identity-server/api-resources", + component: "/identity-server/api-resources/index", + description: "Api 资源", + multiTenancySides: MultiTenancySides.Host)); + identityServer.AddItem( + new ApplicationMenu( + name: "IdentityResources", + displayName: "身份资源", + url: "/manage/identity-server/identity-resources", + component: "/identity-server/identity-resources/index", + description: "身份资源", + multiTenancySides: MultiTenancySides.Host)); + identityServer.AddItem( + new ApplicationMenu( + name: "ApiScopes", + displayName: "Api 范围", + url: "/manage/identity-server/api-scopes", + component: "/identity-server/api-scopes/index", + description: "Api 范围", + multiTenancySides: MultiTenancySides.Host)); + identityServer.AddItem( + new ApplicationMenu( + name: "PersistedGrants", + displayName: "持久授权", + url: "/manage/identity-server/persisted-grants", + component: "/identity-server/persisted-grants/index", + description: "持久授权", + multiTenancySides: MultiTenancySides.Host)); + + + manage.AddItem( + new ApplicationMenu( + name: "Logs", + displayName: "系统日志", + url: "/sys/logs", + component: "/sys/logging/index", + description: "系统日志")); + + return new NavigationDefinition(manage); + } + + private static NavigationDefinition GetSaas() + { + var saas = new ApplicationMenu( + name: "Saas", + displayName: "Saas", + url: "/saas", + component: "", + description: "Saas", + icon: "ant-design:cloud-server-outlined", + multiTenancySides: MultiTenancySides.Host); + saas.AddItem( + new ApplicationMenu( + name: "Tenants", + displayName: "租户管理", + url: "/saas/tenants", + component: "/saas/tenant/index", + description: "租户管理", + multiTenancySides: MultiTenancySides.Host)); + + return new NavigationDefinition(saas); + } + + private static NavigationDefinition GetPlatform() + { + var platform = new ApplicationMenu( + name: "Platform", + displayName: "平台管理", + url: "/platform", + component: "", + description: "平台管理"); + platform.AddItem( + new ApplicationMenu( + name: "DataDictionary", + displayName: "数据字典", + url: "/platform/data-dic", + component: "/platform/dataDic/index", + description: "数据字典")); + platform.AddItem( + new ApplicationMenu( + name: "Layout", + displayName: "布局", + url: "/platform/layout", + component: "/platform/layout/index", + description: "布局")); + platform.AddItem( + new ApplicationMenu( + name: "Menu", + displayName: "菜单", + url: "/platform/menu", + component: "/platform/menu/index", + description: "菜单")); + + return new NavigationDefinition(platform); + } + + private static NavigationDefinition GetApiGateway() + { + var apiGateway = new ApplicationMenu( + name: "ApiGateway", + displayName: "网关管理", + url: "/api-gateway", + component: "", + description: "网关管理", + icon: "ant-design:gateway-outlined", + multiTenancySides: MultiTenancySides.Host); + apiGateway.AddItem( + new ApplicationMenu( + name: "RouteGroup", + displayName: "路由分组", + url: "/api-gateway/group", + component: "/api-gateway/group/index", + description: "路由分组", + multiTenancySides: MultiTenancySides.Host)); + apiGateway.AddItem( + new ApplicationMenu( + name: "GlobalConfiguration", + displayName: "公共配置", + url: "/api-gateway/global", + component: "/api-gateway/global/index", + description: "公共配置", + multiTenancySides: MultiTenancySides.Host)); + apiGateway.AddItem( + new ApplicationMenu( + name: "Route", + displayName: "路由管理", + url: "/api-gateway/route", + component: "/api-gateway/route/index", + description: "路由管理", + multiTenancySides: MultiTenancySides.Host)); + apiGateway.AddItem( + new ApplicationMenu( + name: "AggregateRoute", + displayName: "聚合路由", + url: "/api-gateway/aggregate", + component: "/api-gateway/aggregate/index", + description: "聚合路由", + multiTenancySides: MultiTenancySides.Host)); + + return new NavigationDefinition(apiGateway); + } + + private static NavigationDefinition GetLocalization() + { + var localization = new ApplicationMenu( + name: "Localization", + displayName: "本地化管理", + url: "/localization", + component: "", + description: "本地化管理", + icon: "ant-design:translation-outlined", + multiTenancySides: MultiTenancySides.Host); + localization.AddItem( + new ApplicationMenu( + name: "Languages", + displayName: "语言管理", + url: "/localization/languages", + component: "/localization/languages/index", + description: "语言管理", + multiTenancySides: MultiTenancySides.Host) + ); + localization.AddItem( + new ApplicationMenu( + name: "Resources", + displayName: "资源管理", + url: "/localization/resources", + component: "/localization/resources/index", + description: "资源管理", + multiTenancySides: MultiTenancySides.Host) + ); + localization.AddItem( + new ApplicationMenu( + name: "Texts", + displayName: "文档管理", + url: "/localization/texts", + component: "/localization/texts/index", + description: "文档管理", + multiTenancySides: MultiTenancySides.Host) + ); + + return new NavigationDefinition(localization); + } + + private static NavigationDefinition GetOssManagement() + { + var oss = new ApplicationMenu( + name: "OssManagement", + displayName: "对象存储", + url: "/oss", + component: "", + description: "对象存储", + icon: "ant-design:file-twotone"); + oss.AddItem( + new ApplicationMenu( + name: "Containers", + displayName: "容器管理", + url: "/oss/containers", + component: "/oss-management/containers/index", + description: "容器管理")); + oss.AddItem( + new ApplicationMenu( + name: "Objects", + displayName: "文件管理", + url: "/oss/objects", + component: "/oss-management/objects/index", + description: "文件管理")); + + return new NavigationDefinition(oss); + } + } +} diff --git a/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminOptions.cs b/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminOptions.cs new file mode 100644 index 000000000..4dce95725 --- /dev/null +++ b/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/LINGYUN/Abp/UI/Navigation/VueVbenAdmin/AbpUINavigationVueVbenAdminOptions.cs @@ -0,0 +1,15 @@ +namespace LINGYUN.Abp.UI.Navigation.VueVbenAdmin +{ + public class AbpUINavigationVueVbenAdminOptions + { + public string UI { get; set; } + public string LayoutName { get; set; } + public string LayoutPath { get; set; } + public AbpUINavigationVueVbenAdminOptions() + { + UI = "Vue Vben Admin"; + LayoutName = "Vben Admin Layout"; + LayoutPath = "LAYOUT"; + } + } +} diff --git a/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/README.md b/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/README.md new file mode 100644 index 000000000..699aca2dc --- /dev/null +++ b/aspnet-core/modules/platform/LINGYUN.Abp.UI.Navigation.VueVbenAdmin/README.md @@ -0,0 +1,21 @@ +# LINGYUN.Abp.UI.Navigation.VueVbenAdmin + +适用于 **abp-vue-vben-admin** 的初始化菜单数据模块 + +## 配置使用 + +```csharp +[DependsOn(typeof(AbpUINavigationVueVbenAdminModule))] +public class YouProjectModule : AbpModule +{ + // other +} +``` + +## 配置项 + +* AbpUINavigationVueVbenAdminOptions.UI UI名称,默认值: Vue Vben Admin,不建议变更,否则需要改变前端 +* AbpUINavigationVueVbenAdminOptions.LayoutName 布局名称,默认值: Vben Admin Layout,不建议变更,否则需要改变前端 +* AbpUINavigationVueVbenAdminOptions.LayoutPath 布局组件,默认值: LAYOUT,不建议变更,否则需要改变前端 + +## 其他 diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs index d31c487d7..8f4028887 100644 --- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs +++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs @@ -12,6 +12,7 @@ using LINGYUN.Abp.OssManagement.FileSystem; using LINGYUN.Abp.OssManagement.FileSystem.ImageSharp; using LINGYUN.Abp.OssManagement.SettingManagement; using LINGYUN.Abp.Serilog.Enrichers.Application; +using LINGYUN.Abp.UI.Navigation.VueVbenAdmin; using LINGYUN.Platform.EntityFrameworkCore; using LINGYUN.Platform.HttpApi; using Microsoft.AspNetCore.Builder; @@ -40,6 +41,7 @@ namespace LINGYUN.Platform typeof(AbpAspNetCoreSerilogModule), typeof(AbpAuditLoggingElasticsearchModule), typeof(AbpAspNetCoreMultiTenancyModule), + typeof(AbpUINavigationVueVbenAdminModule), // typeof(AbpOssManagementAliyunModule), typeof(AbpOssManagementFileSystemModule), // 本地文件系统提供者模块 typeof(AbpOssManagementFileSystemImageSharpModule), // 本地文件系统图形处理模块 diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/DataSeeder/ElementAdminDataSeedContributor.cs b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/DataSeeder/ElementAdminDataSeedContributor.cs deleted file mode 100644 index f8a309218..000000000 --- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/DataSeeder/ElementAdminDataSeedContributor.cs +++ /dev/null @@ -1,962 +0,0 @@ -using LINGYUN.Platform.Datas; -using LINGYUN.Platform.Layouts; -using LINGYUN.Platform.Menus; -using LINGYUN.Platform.Routes; -using LINGYUN.Platform.Utils; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Volo.Abp.Data; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Guids; -using Volo.Abp.MultiTenancy; - -namespace LINGYUN.Platform.DataSeeder -{ - public class ElementAdminDataSeedContributor : IDataSeedContributor, ITransientDependency - { - protected ICurrentTenant CurrentTenant { get; } - protected IGuidGenerator GuidGenerator { get; } - protected IRouteDataSeeder RouteDataSeeder { get; } - protected IDataDictionaryDataSeeder DataDictionaryDataSeeder { get; } - protected IMenuRepository MenuRepository { get; } - protected ILayoutRepository LayoutRepository { get; } - - public ElementAdminDataSeedContributor( - ICurrentTenant currentTenant, - IRouteDataSeeder routeDataSeeder, - IMenuRepository menuRepository, - ILayoutRepository layoutRepository, - IGuidGenerator guidGenerator, - IDataDictionaryDataSeeder dataDictionaryDataSeeder) - { - CurrentTenant = currentTenant; - GuidGenerator = guidGenerator; - RouteDataSeeder = routeDataSeeder; - MenuRepository = menuRepository; - LayoutRepository = layoutRepository; - DataDictionaryDataSeeder = dataDictionaryDataSeeder; - } - - public virtual async Task SeedAsync(DataSeedContext context) - { - await Task.CompletedTask; - //using (CurrentTenant.Change(context.TenantId)) - //{ - // var uiItem = await SeedUIFrameworkDataAsync(context.TenantId); - // var data = await SeedLayoutDataAsync(context.TenantId); - // // 预置 - // var layout = await SeedDefaultLayoutAsync(data, uiItem); - // // 首页 - // await SeedHomeMenuAsync(layout, data); - // // 管理菜单预置菜单数据 - // await SeedAdminMenuAsync(layout, data); - // // saas菜单数据 - // await SeedSaasMenuAsync(layout, data); - // // 身份资源菜单数据 - // await SeedIdentityServerMenuAsync(layout, data); - // // 审计日志菜单数据 - // await SeedAuditingMenuAsync(layout, data); - // // 布局容器预置菜单数据 - // await SeedContainerMenuAsync(layout, data); - // // 网关管理菜单数据 - // await SeedApiGatewayMenuAsync(layout, data); - // // Oss对象管理菜单数据 - // await SeedOssManagementMenuAsync(layout, data); - // // 本地化管理菜单数据 - // await SeedLocalizationManagementMenuAsync(layout, data); - //} - } - - private async Task SeedUIFrameworkDataAsync(Guid? tenantId) - { - var data = await DataDictionaryDataSeeder - .SeedAsync( - "UI Framework", - CodeNumberGenerator.CreateCode(2), - "UI框架", - "UI Framework", - null, - tenantId, - true); - - data.AddItem( - GuidGenerator, - "Vue Element Admin", - "Vue Element Admin", - "Vue Element Admin", - Datas.ValueType.String, - "Vue Element Admin", - isStatic: true); - - return data.FindItem("Vue Element Admin"); - } - - private async Task SeedLayoutDataAsync(Guid? tenantId) - { - var data = await DataDictionaryDataSeeder - .SeedAsync( - "Layout", - CodeNumberGenerator.CreateCode(1), - "Vue Admin Layout Meta Dictionary", - "Vue Admin Layout Meta Dictionary", - null, - tenantId, - true); - - data.AddItem( - GuidGenerator, - "roles", // TODO: 是否需要把这一项写入到预置数据? - "roles", - "", - Datas.ValueType.Array, - "will control the page roles (allow setting multiple roles)", - isStatic: true); - data.AddItem( - GuidGenerator, - "title", - "title", - "component", - Datas.ValueType.String, - "the name showed in subMenu and breadcrumb (recommend set)", - isStatic: true); - data.AddItem( - GuidGenerator, - "icon", - "icon", - "icon", - Datas.ValueType.String, - "the icon showed in the sidebar", - isStatic: true); - data.AddItem( - GuidGenerator, - "hidden", - "hidden", - "false", - Datas.ValueType.Boolean, - "if true, this route will not show in the sidebar (default is false)", - isStatic: true); - data.AddItem( - GuidGenerator, - "alwaysShow", - "alwaysShow", - "false", - Datas.ValueType.Boolean, - "if true, will always show the root menu (default is false)", - isStatic: true); - data.AddItem( - GuidGenerator, - "breadcrumb", - "breadcrumb", - "true", - Datas.ValueType.Boolean, - "if false, the item will be hidden in breadcrumb (default is true)", - isStatic: true); - data.AddItem( - GuidGenerator, - "noCache", - "noCache", - "false", - Datas.ValueType.Boolean, - "if true, the page will not be cached (default is false)", - isStatic: true); - data.AddItem( - GuidGenerator, - "affix", - "affix", - "false", - Datas.ValueType.Boolean, - "if true, the tag will affix in the tags-view", - isStatic: true); - data.AddItem( - GuidGenerator, - "activeMenu", - "activeMenu", - "", - Datas.ValueType.String, - "if set path, the sidebar will highlight the path you set", - isStatic: true); - - return data; - } - - private async Task SeedDefaultLayoutAsync(Data data, DataItem uiDataItem) - { - var layout = await RouteDataSeeder.SeedLayoutAsync( - "Layout", - "layout/index.vue", - "Vue Admin Layout", - data.Id, - uiDataItem.Name, - "", - "Vue Admin Layout", - data.TenantId - ); - - return layout; - } - - private async Task SeedHomeMenuAsync(Layout layout, Data data) - { - var adminMenu = await SeedMenuAsync( - layout, - data, - "home", - "/", - CodeNumberGenerator.CreateCode(1), - layout.Path, - "Home", - "/dashboard", - "Home", - null, - layout.TenantId, - new Dictionary() - { - { "title", "home" }, - { "icon", "home" }, - { "alwaysShow", true } - }, - // isPublic: true, - isPublic: false); // 首页应该是共有的页面 - - await SeedMenuAsync( - layout, - data, - "dashboard", - "dashboard", - CodeNumberGenerator.AppendCode(adminMenu.Code, CodeNumberGenerator.CreateCode(1)), - "views/dashboard/index.vue", - "Dashboard", - "", - "Dashboard", - adminMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "dashboard" }, - { "icon", "dashboard" } - }, - isPublic: false); - } - - private async Task SeedAdminMenuAsync(Layout layout, Data data) - { - var adminMenu = await SeedMenuAsync( - layout, - data, - "admin", - "/admin", - CodeNumberGenerator.CreateCode(2), - layout.Path, - "Admin", - "", - "Admin", - null, - layout.TenantId, - new Dictionary() - { - { "title", "admin" }, - { "icon", "admin" }, - { "alwaysShow", true } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "roles", - "roles", - CodeNumberGenerator.AppendCode(adminMenu.Code, CodeNumberGenerator.CreateCode(1)), - "views/admin/roles/index.vue", - "Manage Roles", - "", - "Manage Roles", - adminMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "roles" }, - { "icon", "role" }, - { "roles", new string[] { "AbpIdentity.Roles" } } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "users", - "users", - CodeNumberGenerator.AppendCode(adminMenu.Code, CodeNumberGenerator.CreateCode(2)), - "views/admin/users/index.vue", - "Manage Users", - "", - "Manage Users", - adminMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "users" }, - { "icon", "users" }, - { "roles", new string[] { "AbpIdentity.Users" } } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "organization-unit", - "organization-unit", - CodeNumberGenerator.AppendCode(adminMenu.Code, CodeNumberGenerator.CreateCode(3)), - "views/admin/organization-unit/index.vue", - "Manage Organization Units", - "", - "Manage Organization Units", - adminMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "organization-unit" }, - { "icon", "organization-unit" }, - { "roles", new string[] { "AbpIdentity.OrganizationUnits" } } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "claim-type", - "claim-type", - CodeNumberGenerator.AppendCode(adminMenu.Code, CodeNumberGenerator.CreateCode(4)), - "views/admin/claim-type/index.vue", - "Manage Claim Types", - "", - "Manage Claim Types", - adminMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "claim-type" }, - { "icon", "claim-type" }, - { "roles", new string[] { "AbpIdentity.IdentityClaimTypes" } } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "data-dictionary", - "data-dictionary", - CodeNumberGenerator.AppendCode(adminMenu.Code, CodeNumberGenerator.CreateCode(5)), - "views/admin/data-dictionary/index.vue", - "Manage Data Dictionarys", - "", - "Manage Data Dictionarys", - adminMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "data-dictionary" }, - { "icon", "data-dictionary" }, - { "roles", new string[] { "Platform.DataDictionary" } } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "settings", - "settings", - CodeNumberGenerator.AppendCode(adminMenu.Code, CodeNumberGenerator.CreateCode(6)), - "views/admin/settings/index.vue", - "Manage Settings", - "", - "Manage Settings", - adminMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "settings" }, - { "icon", "settings" }, - { "roles", new string[] { "AbpSettingManagement.Settings" } } - }, - new string[] { "admin" }); - } - - private async Task SeedSaasMenuAsync(Layout layout, Data data) - { - var saasMenu = await SeedMenuAsync( - layout, - data, - "saas", - "/saas", - CodeNumberGenerator.CreateCode(3), - layout.Path, - "Saas", - "", - "Saas", - null, - layout.TenantId, - new Dictionary() - { - { "title", "saas" }, - { "icon", "saas" }, - { "alwaysShow", true } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "editions", - "editions", - CodeNumberGenerator.AppendCode(saasMenu.Code, CodeNumberGenerator.CreateCode(1)), - "views/admin/edition/index.vue", - "Manage Editions", - "", - "Manage Editions", - saasMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "editions" }, - { "icon", "editions" } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "tenants", - "tenants", - CodeNumberGenerator.AppendCode(saasMenu.Code, CodeNumberGenerator.CreateCode(2)), - "views/admin/tenants/index.vue", - "Manage Tenants", - "", - "Manage Tenants", - saasMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "tenants" }, - { "icon", "tenants" } - }, - new string[] { "admin" }); - } - - private async Task SeedIdentityServerMenuAsync(Layout layout, Data data) - { - var identityServerMenu = await SeedMenuAsync( - layout, - data, - "identity-server", - "/identity-server", - CodeNumberGenerator.CreateCode(4), - layout.Path, - "Identity Server", - "", - "Identity Server", - null, - layout.TenantId, - new Dictionary() - { - { "title", "identity-server" }, - { "icon", "identity-server" }, - { "alwaysShow", true }, - { "roles", new string[]{ "AbpIdentityServer.Clients", "AbpIdentityServer.ApiResources", "AbpIdentityServer.IdentityResources", "AbpIdentityServer.ApiScopes" } } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "clients", - "clients", - CodeNumberGenerator.AppendCode(identityServerMenu.Code, CodeNumberGenerator.CreateCode(1)), - "views/admin/identityServer/client/index.vue", - "Manage Clients", - "", - "Manage Clients", - identityServerMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "clients" }, - { "icon", "client" }, - { "roles", new string[]{ "AbpIdentityServer.Clients" } } - }, - new string[] { "admin" }); - await SeedMenuAsync( - layout, - data, - "api-resources", - "api-resources", - CodeNumberGenerator.AppendCode(identityServerMenu.Code, CodeNumberGenerator.CreateCode(2)), - "views/admin/identityServer/api-resources/index.vue", - "Manage Api Resources", - "", - "Manage Api Resources", - identityServerMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "api-resources" }, - { "icon", "api" }, - { "roles", new string[]{ "AbpIdentityServer.ApiResources" } } - }, - new string[] { "admin" }); - await SeedMenuAsync( - layout, - data, - "identity-resources", - "identity-resources", - CodeNumberGenerator.AppendCode(identityServerMenu.Code, CodeNumberGenerator.CreateCode(3)), - "views/admin/identityServer/identity-resources/index.vue", - "Manage Identity Resources", - "", - "Manage Identity Resources", - identityServerMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "identity-resources" }, - { "icon", "identity" }, - { "roles", new string[]{ "AbpIdentityServer.IdentityResources" } } - }, - new string[] { "admin" }); - await SeedMenuAsync( - layout, - data, - "api-scopes", - "api-scopes", - CodeNumberGenerator.AppendCode(identityServerMenu.Code, CodeNumberGenerator.CreateCode(4)), - "views/admin/identityServer/api-scopes/index.vue", - "Manage Api Scopes", - "", - "Manage Api Scopes", - identityServerMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "api-scopes" }, - { "icon", "api-scopes" }, - { "roles", new string[]{ "AbpIdentityServer.ApiScopes" } } - }, - new string[] { "admin" }); - } - - private async Task SeedAuditingMenuAsync(Layout layout, Data data) - { - var auditingMenu = await SeedMenuAsync( - layout, - data, - "auditing", - "/auditing", - CodeNumberGenerator.CreateCode(5), - layout.Path, - "Auditing", - "", - "Auditing", - null, - layout.TenantId, - new Dictionary() - { - { "title", "auditing" }, - { "icon", "auditing" }, - { "alwaysShow", true }, - { "roles", new string[]{ "AbpAuditing.AuditLog", "AbpAuditing.SecurityLog" } } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "audit-log", - "audit-log", - CodeNumberGenerator.AppendCode(auditingMenu.Code, CodeNumberGenerator.CreateCode(1)), - "views/admin/auditing/audit-log/index.vue", - "Manage AuditLog", - "", - "Manage AuditLog", - auditingMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "audit-log" }, - { "icon", "audit-log" }, - { "roles", new string[]{ "AbpAuditing.AuditLog" } } - }, - new string[] { "admin" }); - await SeedMenuAsync( - layout, - data, - "security-log", - "security-log", - CodeNumberGenerator.AppendCode(auditingMenu.Code, CodeNumberGenerator.CreateCode(2)), - "views/admin/auditing/security-log/index.vue", - "Manage SecurityLog", - "", - "Manage SecurityLog", - auditingMenu.Id, - layout.TenantId, - new Dictionary() - { - { "title", "security-log" }, - { "icon", "security-log" }, - { "roles", new string[]{ "AbpAuditing.SecurityLog" } } - }, - new string[] { "admin" }); - } - - private async Task SeedContainerMenuAsync(Layout layout, Data data) - { - var containerRoot = await SeedMenuAsync( - layout, - data, - "container", - "/container", - CodeNumberGenerator.CreateCode(6), - layout.Path, - "Container", - "", - "Manage Container", - null, - layout.TenantId, - new Dictionary() - { - { "title", "container" }, - { "icon", "container" }, - { "alwaysShow", true } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "layouts", - "layouts", - CodeNumberGenerator.AppendCode(containerRoot.Code, CodeNumberGenerator.CreateCode(1)), - "views/container/layouts/index.vue", - "Manage Layouts", - "", - "Manage Layouts", - containerRoot.Id, - containerRoot.TenantId, - new Dictionary() - { - { "title", "layouts" }, - { "icon", "layout" } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "menus", - "menus", - CodeNumberGenerator.AppendCode(containerRoot.Code, CodeNumberGenerator.CreateCode(2)), - "views/container/menus/index.vue", - "Manage Menus", - "", - "Manage Menus", - containerRoot.Id, - containerRoot.TenantId, - new Dictionary() - { - { "title", "menus" }, - { "icon", "menu" } - }, - new string[] { "admin" }); - } - - private async Task SeedApiGatewayMenuAsync(Layout layout, Data data) - { - var apiGatewayMenu = await SeedMenuAsync( - layout, - data, - "apigateway", - "/apigateway", - CodeNumberGenerator.CreateCode(7), - layout.Path, - "Manage Api Gateway", - "/group", - "Manage Api Gateway", - null, - layout.TenantId, - new Dictionary() - { - { "title", "api-gateway" }, - { "icon", "api-gateway" }, - { "alwaysShow", true }, - { "roles", new string[] { "ApiGateway.RouteGroup", "ApiGateway.Global", "ApiGateway.Route", "ApiGateway.DynamicRoute", "ApiGateway.AggregateRoute" } }, - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "group", - "group", - CodeNumberGenerator.AppendCode(apiGatewayMenu.Code, CodeNumberGenerator.CreateCode(1)), - "views/admin/apigateway/group.vue", - "Manage Groups", - "", - "Manage Groups", - apiGatewayMenu.Id, - apiGatewayMenu.TenantId, - new Dictionary() - { - { "title", "group" }, - { "icon", "group" }, - { "roles", new string[] { "ApiGateway.RouteGroup" } } - }, - new string[] { "admin" }); - await SeedMenuAsync( - layout, - data, - "global", - "global", - CodeNumberGenerator.AppendCode(apiGatewayMenu.Code, CodeNumberGenerator.CreateCode(2)), - "views/admin/apigateway/global.vue", - "Manage Globals", - "", - "Manage Globals", - apiGatewayMenu.Id, - apiGatewayMenu.TenantId, - new Dictionary() - { - { "title", "global" }, - { "icon", "global-setting" }, - { "roles", new string[] { "ApiGateway.Global" } } - }, - new string[] { "admin" }); - await SeedMenuAsync( - layout, - data, - "route", - "route", - CodeNumberGenerator.AppendCode(apiGatewayMenu.Code, CodeNumberGenerator.CreateCode(3)), - "views/admin/apigateway/route.vue", - "Manage Routes", - "", - "Manage Routes", - apiGatewayMenu.Id, - apiGatewayMenu.TenantId, - new Dictionary() - { - { "title", "route" }, - { "icon", "route" }, - { "roles", new string[] { "ApiGateway.Route" } } - }, - new string[] { "admin" }); - await SeedMenuAsync( - layout, - data, - "aggregate-route", - "aggregate-route", - CodeNumberGenerator.AppendCode(apiGatewayMenu.Code, CodeNumberGenerator.CreateCode(4)), - "views/admin/apigateway/aggregateRoute.vue", - "Manage Aggregate Routes", - "", - "Manage Aggregate Routes", - apiGatewayMenu.Id, - apiGatewayMenu.TenantId, - new Dictionary() - { - { "title", "aggregate-route" }, - { "icon", "aggregate" }, - { "roles", new string[] { "ApiGateway.AggregateRoute " } } - }, - new string[] { "admin" }); - } - - private async Task SeedOssManagementMenuAsync(Layout layout, Data data) - { - var ossManagementMenu = await SeedMenuAsync( - layout, - data, - "oss-management", - "/oss-management", - CodeNumberGenerator.CreateCode(8), - layout.Path, - "Manage Object Storage", - "/oss-manager", - "Manage Object Storage", - null, - layout.TenantId, - new Dictionary() - { - { "title", "oss-management" }, - { "icon", "file-system" }, - { "alwaysShow", true }, - { "roles", new string[] { "AbpOssManagement.Container", "AbpOssManagement.OssObject" } }, - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "oss-manager", - "oss-manager", - CodeNumberGenerator.AppendCode(ossManagementMenu.Code, CodeNumberGenerator.CreateCode(1)), - "views/oss-management/index.vue", - "Manage Oss Object", - "", - "Manage Oss Object", - ossManagementMenu.Id, - ossManagementMenu.TenantId, - new Dictionary() - { - { "title", "oss-objects" }, - { "icon", "file-system" }, - { "roles", new string[] { "AbpOssManagement.OssObject" } } - }, - new string[] { "admin" }); - } - - private async Task SeedLocalizationManagementMenuAsync(Layout layout, Data data) - { - var localizationManagementMenu = await SeedMenuAsync( - layout, - data, - "localization-management", - "/localization-management", - CodeNumberGenerator.CreateCode(9), - layout.Path, - "Manage Localization", - "/localization", - "Manage Localization", - null, - layout.TenantId, - new Dictionary() - { - { "title", "localization" }, - { "icon", "localization" }, - { "alwaysShow", true }, - { "roles", new string[] { "LocalizationManagement.Resource", "LocalizationManagement.Language", "LocalizationManagement.Text" } }, - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "resource", - "resource", - CodeNumberGenerator.AppendCode(localizationManagementMenu.Code, CodeNumberGenerator.CreateCode(1)), - "views/localization-management/resources/index.vue", - "Manage Resource", - "", - "Manage Resource", - localizationManagementMenu.Id, - localizationManagementMenu.TenantId, - new Dictionary() - { - { "title", "resource" }, - { "icon", "resource" }, - { "roles", new string[] { "LocalizationManagement.Resource" } } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "language", - "language", - CodeNumberGenerator.AppendCode(localizationManagementMenu.Code, CodeNumberGenerator.CreateCode(2)), - "views/localization-management/languages/index.vue", - "Manage Language", - "", - "Manage Language", - localizationManagementMenu.Id, - localizationManagementMenu.TenantId, - new Dictionary() - { - { "title", "language" }, - { "icon", "language" }, - { "roles", new string[] { "LocalizationManagement.Language" } } - }, - new string[] { "admin" }); - - await SeedMenuAsync( - layout, - data, - "text", - "text", - CodeNumberGenerator.AppendCode(localizationManagementMenu.Code, CodeNumberGenerator.CreateCode(3)), - "views/localization-management/texts/index.vue", - "Manage Text", - "", - "Manage Text", - localizationManagementMenu.Id, - localizationManagementMenu.TenantId, - new Dictionary() - { - { "title", "text" }, - { "icon", "text" }, - { "roles", new string[] { "LocalizationManagement.Text" } } - }, - new string[] { "admin" }); - - } - private async Task SeedMenuAsync( - Layout layout, - Data data, - string name, - string path, - string code, - string component, - string displayName, - string redirect = "", - string description = "", - Guid? parentId = null, - Guid? tenantId = null, - Dictionary meta = null, - string[] roles = null, - Guid[] users = null, - bool isPublic = false - ) - { - var menu = await RouteDataSeeder.SeedMenuAsync( - layout, - name, - path, - code, - component, - displayName, - redirect, - description, - parentId, - tenantId, - isPublic - ); - foreach (var item in data.Items) - { - menu.SetProperty(item.Name, item.DefaultValue); - } - if (meta != null) - { - foreach (var item in meta) - { - menu.SetProperty(item.Key, item.Value); - } - } - - if (roles != null) - { - foreach (var role in roles) - { - await RouteDataSeeder.SeedRoleMenuAsync(role, menu, tenantId); - } - } - - if (users != null) - { - foreach (var user in users) - { - await RouteDataSeeder.SeedUserMenuAsync(user, menu, tenantId); - } - } - - return menu; - } - } -} \ No newline at end of file diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/DataSeeder/VbenAdminDataSeedContributor.cs b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/DataSeeder/VbenAdminDataSeedContributor.cs deleted file mode 100644 index f2c227722..000000000 --- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/DataSeeder/VbenAdminDataSeedContributor.cs +++ /dev/null @@ -1,1089 +0,0 @@ -using LINGYUN.Platform.Datas; -using LINGYUN.Platform.Layouts; -using LINGYUN.Platform.Menus; -using LINGYUN.Platform.Routes; -using LINGYUN.Platform.Utils; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Volo.Abp.Data; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Guids; -using Volo.Abp.MultiTenancy; - -namespace LINGYUN.Platform.DataSeeder -{ - public class VbenAdminDataSeedContributor : IDataSeedContributor, ITransientDependency - { - protected ICurrentTenant CurrentTenant { get; } - protected IGuidGenerator GuidGenerator { get; } - protected IRouteDataSeeder RouteDataSeeder { get; } - protected IDataDictionaryDataSeeder DataDictionaryDataSeeder { get; } - protected IMenuRepository MenuRepository { get; } - protected ILayoutRepository LayoutRepository { get; } - - public VbenAdminDataSeedContributor( - ICurrentTenant currentTenant, - IRouteDataSeeder routeDataSeeder, - IMenuRepository menuRepository, - ILayoutRepository layoutRepository, - IGuidGenerator guidGenerator, - IDataDictionaryDataSeeder dataDictionaryDataSeeder) - { - CurrentTenant = currentTenant; - GuidGenerator = guidGenerator; - RouteDataSeeder = routeDataSeeder; - MenuRepository = menuRepository; - LayoutRepository = layoutRepository; - DataDictionaryDataSeeder = dataDictionaryDataSeeder; - } - - public virtual async Task SeedAsync(DataSeedContext context) - { - using (CurrentTenant.Change(context.TenantId)) - { - var uiDataItem = await SeedUIFrameworkDataAsync(context.TenantId); - - var layoutData = await SeedLayoutDataAsync(context.TenantId); - - var layout = await SeedDefaultLayoutAsync(layoutData, uiDataItem); - - // 首页数据 - await SeedHomeMenuAsync(layout, layoutData); - // 仪表盘 - await SeedDashboardMenuAsync(layout, layoutData); - // 管理菜单 - await SeedManageMenuAsync(layout, layoutData); - // 平台菜单 - await SeedPlatformMenuAsync(layout, layoutData); - // 对象存储菜单 - await SeedOssManagementMenuAsync(layout, layoutData); - - // 特定于宿主的菜单不能写入到租户数据中 - if (!context.TenantId.HasValue) - { - // 多语言菜单 - await SeedLocalizationMenuAsync(layout, layoutData); - // Saas菜单 - await SeedSaasMenuAsync(layout, layoutData); - // 网关菜单 - await SeedApiGatewayMenuAsync(layout, layoutData); - } - } - } - - private async Task SeedUIFrameworkDataAsync(Guid? tenantId) - { - var data = await DataDictionaryDataSeeder - .SeedAsync( - "UI Framework", - CodeNumberGenerator.CreateCode(2), - "UI框架", - "UI Framework", - null, - tenantId, - true); - - data.AddItem( - GuidGenerator, - "Vue Vben Admin", - "Vue Vben Admin", - "Vue Vben Admin", - Datas.ValueType.String, - "Vue Vben Admin", - isStatic: true); - - return data.FindItem("Vue Vben Admin"); - } - - private async Task SeedDefaultLayoutAsync(Data data, DataItem uiDataItem) - { - var layout = await RouteDataSeeder.SeedLayoutAsync( - "Vben Admin Layout", - "LAYOUT", // 路由层面已经处理好了,只需要传递LAYOUT可自动引用布局 - "Vben Admin Layout", - data.Id, - uiDataItem.Name, - "", - "Vben Admin Layout", - data.TenantId - ); - - return layout; - } - - private async Task SeedLayoutDataAsync(Guid? tenantId) - { - var data = await DataDictionaryDataSeeder - .SeedAsync( - "Vben Admin Layout", - CodeNumberGenerator.CreateCode(3), - "Vben Admin布局约束", - "Vben Admin Layout Meta Dictionary", - null, - tenantId, - true); - - data.AddItem( - GuidGenerator, - "hideMenu", - "不在菜单显示", - "false", - Datas.ValueType.Boolean, - "当前路由不在菜单显示", - isStatic: true); - data.AddItem( - GuidGenerator, - "icon", - "图标", - "", - Datas.ValueType.String, - "图标,也是菜单图标", - isStatic: true); - data.AddItem( - GuidGenerator, - "currentActiveMenu", - "当前激活的菜单", - "", - Datas.ValueType.String, - "用于配置详情页时左侧激活的菜单路径", - isStatic: true); - data.AddItem( - GuidGenerator, - "ignoreKeepAlive", - "KeepAlive缓存", - "false", - Datas.ValueType.Boolean, - "是否忽略KeepAlive缓存", - isStatic: true); - data.AddItem( - GuidGenerator, - "frameSrc", - "IFrame地址", - "", - Datas.ValueType.String, - "内嵌iframe的地址", - isStatic: true); - data.AddItem( - GuidGenerator, - "transitionName", - "路由切换动画", - "", - Datas.ValueType.String, - "指定该路由切换的动画名", - isStatic: true); - data.AddItem( - GuidGenerator, - "roles", - "可以访问的角色", - "", - Datas.ValueType.Array, - "可以访问的角色,只在权限模式为Role的时候有效", - isStatic: true); - data.AddItem( - GuidGenerator, - "title", - "路由标题", - "", - Datas.ValueType.String, - "路由title 一般必填", - false, - isStatic: true); - data.AddItem( - GuidGenerator, - "carryParam", - "在tab页显示", - "false", - Datas.ValueType.Boolean, - "如果该路由会携带参数,且需要在tab页上面显示。则需要设置为true", - isStatic: true); - data.AddItem( - GuidGenerator, - "hideBreadcrumb", - "隐藏面包屑", - "false", - Datas.ValueType.Boolean, - "隐藏该路由在面包屑上面的显示", - isStatic: true); - data.AddItem( - GuidGenerator, - "ignoreAuth", - "忽略权限", - "false", - Datas.ValueType.Boolean, - "是否忽略权限,只在权限模式为Role的时候有效", - isStatic: true); - data.AddItem( - GuidGenerator, - "hideChildrenInMenu", - "隐藏所有子菜单", - "false", - Datas.ValueType.Boolean, - "隐藏所有子菜单", - isStatic: true); - data.AddItem( - GuidGenerator, - "hideTab", - "不在标签页显示", - "false", - Datas.ValueType.Boolean, - "当前路由不在标签页显示", - isStatic: true); - data.AddItem( - GuidGenerator, - "affix", - "固定标签页", - "false", - Datas.ValueType.Boolean, - "是否固定标签页", - isStatic: true); - data.AddItem( - GuidGenerator, - "frameFormat", - "格式化IFrame", - "false", - Datas.ValueType.Boolean, - "扩展的格式化frame,{token}: 在打开的iframe页面传递token请求头"); - - return data; - } - - private async Task SeedHomeMenuAsync(Layout layout, Data data) - { - await SeedMenuAsync( - layout, - data, - "Vben Home", - "/home", - CodeNumberGenerator.CreateCode(20), - "/dashboard/welcome/index", - "Home", - "", - "Home", - null, - layout.TenantId, - new Dictionary() - { - { "title", "routes.dashboard.welcome" }, - { "icon", "ant-design:home-outlined" }, - { "hideTab", false }, - { "ignoreAuth", true }, - }, - isPublic: false); - } - - private async Task SeedDashboardMenuAsync(Layout layout, Data data) - { - var menu = await SeedMenuAsync( - layout, //layout - data, //data - "Vben Dashboard", //name - "/dashboard", //path - CodeNumberGenerator.CreateCode(21), //code - layout.Path, //component - "仪表盘", //displayName - "/dashboard/analysis", //redirect - "仪表盘", //description - null, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "仪表盘" }, - { "icon", "ant-design:home-outlined" }, - { "hideTab", false }, - { "ignoreAuth", true }, - }, - new string[] { "admin" }); - - var analysis = await SeedMenuAsync( - layout, //layout - data, //data - "Analysis", //name - "/dashboard/analysis", //path - CodeNumberGenerator.AppendCode(menu.Code, CodeNumberGenerator.CreateCode(1)), //code - "/dashboard/analysis/index", //component - "分析页", //displayName - "", //redirect - "分析页", //description - menu.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "分析页" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - - var workbench = await SeedMenuAsync( - layout, //layout - data, //data - "Workbench", //name - "/dashboard/workbench", //path - CodeNumberGenerator.AppendCode(menu.Code, CodeNumberGenerator.CreateCode(2)), //code - "/dashboard/workbench/index", //component - "工作台", //displayName - "", //redirect - "工作台", //description - menu.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "工作台" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - } - - private async Task SeedManageMenuAsync(Layout layout, Data data) - { - var manage = await SeedMenuAsync( - layout, //layout - data, //data - "Manage", //name - "/manage", //path - CodeNumberGenerator.CreateCode(22), //code - layout.Path, //component - "管理", //displayName - "", //redirect - "管理", //description - null, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "管理" }, - { "icon", "ant-design:control-outlined" }, - { "hideTab", false }, - { "ignoreAuth", false }, - }, - new string[] { "admin" }); - - var identity = await SeedMenuAsync( - layout, //layout - data, //data - "Identity", //name - "/manage/identity", //path - CodeNumberGenerator.AppendCode(manage.Code, CodeNumberGenerator.CreateCode(1)), //code - layout.Path, //component - "身份认证管理", //displayName - "", //redirect - "身份认证管理", //description - manage.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "身份认证管理" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var user = await SeedMenuAsync( - layout, //layout - data, //data - "User", //name - "/manage/identity/user", //path - CodeNumberGenerator.AppendCode(identity.Code, CodeNumberGenerator.CreateCode(1)), //code - "/identity/user/index", //component - "用户", //displayName - "", //redirect - "用户", //description - identity.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "用户" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var role = await SeedMenuAsync( - layout, //layout - data, //data - "Role", //name - "/manage/identity/role", //path - CodeNumberGenerator.AppendCode(identity.Code, CodeNumberGenerator.CreateCode(2)), //code - "/identity/role/index", //component - "角色", //displayName - "", //redirect - "角色", //description - identity.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "角色" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var claimTypes = await SeedMenuAsync( - layout, //layout - data, //data - "Claim", //name - "/manage/identity/claim-types", //path - CodeNumberGenerator.AppendCode(identity.Code, CodeNumberGenerator.CreateCode(3)), //code - "/identity/claim-types/index", //component - "身份标识", //displayName - "", //redirect - "身份标识", //description - identity.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "身份标识" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var organizationUnits = await SeedMenuAsync( - layout, //layout - data, //data - "OrganizationUnits", //name - "/manage/identity/organization-units", //path - CodeNumberGenerator.AppendCode(identity.Code, CodeNumberGenerator.CreateCode(4)), //code - "/identity/organization-units/index", //component - "组织机构", //displayName - "", //redirect - "组织机构", //description - identity.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "组织机构" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var securityLog = await SeedMenuAsync( - layout, //layout - data, //data - "SecurityLogs", //name - "/manage/identity/security-logs", //path - CodeNumberGenerator.AppendCode(identity.Code, CodeNumberGenerator.CreateCode(5)), //code - "/identity/security-logs/index", //component - "安全日志", //displayName - "", //redirect - "安全日志", //description - identity.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "安全日志" }, - { "icon", "" }, - { "hideTab", false }, - { "requiredFeatures", "AbpAuditing.Logging.SecurityLog" } // 此路由需要依赖安全日志特性 - }, - new string[] { "admin" }); - - var auditLogs = await SeedMenuAsync( - layout, //layout - data, //data - "AuditLogs", //name - "/manage/audit-logs", //path - CodeNumberGenerator.AppendCode(manage.Code, CodeNumberGenerator.CreateCode(2)), //code - "/auditing/index", //component - "审计日志", //displayName - "", //redirect - "审计日志", //description - manage.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "审计日志" }, - { "icon", "" }, - { "hideTab", false }, - { "requiredFeatures", "AbpAuditing.Logging.AuditLog" } // 此路由需要依赖审计日志特性 - }, - new string[] { "admin" }); - - var settings = await SeedMenuAsync( - layout, //layout - data, //data - "Settings", //name - "/manage/settings", //path - CodeNumberGenerator.AppendCode(manage.Code, CodeNumberGenerator.CreateCode(3)), //code - "/sys/settings/index", //component - "设置", //displayName - "", //redirect - "设置", //description - manage.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "设置" }, - { "icon", "" }, - { "hideTab", false }, - { "requiredFeatures", "SettingManagement.Enable" } // 此路由需要依赖设置管理特性 - }, - new string[] { "admin" }); - - // 特定于宿主的菜单不能写入到租户数据中 - if (!manage.TenantId.HasValue) - { - var identityServer = await SeedMenuAsync( - layout, //layout - data, //data - "IdentityServer", //name - "/manage/identity-server", //path - CodeNumberGenerator.AppendCode(manage.Code, CodeNumberGenerator.CreateCode(4)), //code - layout.Path, //component - "Identity Server", //displayName - "", //redirect - "Identity Server", //description - manage.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "Identity Server" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var clients = await SeedMenuAsync( - layout, //layout - data, //data - "Clients", //name - "/manage/identity-server/clients", //path - CodeNumberGenerator.AppendCode(identityServer.Code, CodeNumberGenerator.CreateCode(1)), //code - "/identity-server/clients/index", //component - "Clients", //displayName - "", //redirect - "Clients", //description - identityServer.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "Clients" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var apiResource = await SeedMenuAsync( - layout, //layout - data, //data - "ApiResources", //name - "/manage/identity-server/api-resources", //path - CodeNumberGenerator.AppendCode(identityServer.Code, CodeNumberGenerator.CreateCode(2)), //code - "/identity-server/api-resources/index", //component - "Api Resources", //displayName - "", //redirect - "Api Resources", //description - identityServer.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "Api Resources" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var identityResources = await SeedMenuAsync( - layout, //layout - data, //data - "IdentityResources", //name - "/manage/identity-server/identity-resources", //path - CodeNumberGenerator.AppendCode(identityServer.Code, CodeNumberGenerator.CreateCode(3)), //code - "/identity-server/identity-resources/index", //component - "Identity Resources", //displayName - "", //redirect - "Identity Resources", //description - identityServer.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "Identity Resources" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var apiScopes = await SeedMenuAsync( - layout, //layout - data, //data - "ApiScopes", //name - "/manage/identity-server/api-scopes", //path - CodeNumberGenerator.AppendCode(identityServer.Code, CodeNumberGenerator.CreateCode(4)), //code - "/identity-server/api-scopes/index", //component - "Api Scopes", //displayName - "", //redirect - "Api Scopes", //description - identityServer.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "Api Scopes" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var persistedGrants = await SeedMenuAsync( - layout, //layout - data, //data - "PersistedGrants", //name - "/manage/identity-server/persisted-grants", //path - CodeNumberGenerator.AppendCode(identityServer.Code, CodeNumberGenerator.CreateCode(5)), //code - "/identity-server/persisted-grants/index", //component - "Persisted Grants", //displayName - "", //redirect - "Persisted Grants", //description - identityServer.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "Persisted Grants" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - } - - var logging = await SeedMenuAsync( - layout, //layout - data, //data - "Logs", //name - "/sys/logs", //path - CodeNumberGenerator.AppendCode(manage.Code, CodeNumberGenerator.CreateCode(5)), //code - "/sys/logging/index", //component - "系统日志", //displayName - "", //redirect - "系统日志", //description - manage.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "系统日志" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - } - - private async Task SeedSaasMenuAsync(Layout layout, Data data) - { - var saas = await SeedMenuAsync( - layout, //layout - data, //data - "Saas", //name - "/saas", //path - CodeNumberGenerator.CreateCode(23), //code - layout.Path, //component - "Saas", //displayName - "", //redirect - "Saas", //description - null, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "Saas" }, - { "icon", "ant-design:cloud-server-outlined" }, - { "hideTab", false }, - { "ignoreAuth", false }, - }, - new string[] { "admin" }); - var tenants = await SeedMenuAsync( - layout, //layout - data, //data - "Tenants", //name - "/saas/tenants", //path - CodeNumberGenerator.AppendCode(saas.Code, CodeNumberGenerator.CreateCode(1)), //code - "/saas/tenant/index", //component - "租户管理", //displayName - "", //redirect - "租户管理", //description - saas.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "租户管理" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - } - - private async Task SeedPlatformMenuAsync(Layout layout, Data data) - { - var platform = await SeedMenuAsync( - layout, //layout - data, //data - "Platform", //name - "/platform", //path - CodeNumberGenerator.CreateCode(24), //code - layout.Path, //component - "平台管理", //displayName - "", //redirect - "平台管理", //description - null, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "平台管理" }, - { "icon", "" }, - { "hideTab", false }, - { "ignoreAuth", false }, - }, - new string[] { "admin" }); - var dataDictionary = await SeedMenuAsync( - layout, //layout - data, //data - "DataDictionary", //name - "/platform/data-dic", //path - CodeNumberGenerator.AppendCode(platform.Code, CodeNumberGenerator.CreateCode(1)), //code - "/platform/dataDic/index", //component - "数据字典", //displayName - "", //redirect - "数据字典", //description - platform.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "数据字典" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var layouts = await SeedMenuAsync( - layout, //layout - data, //data - "Layout", //name - "/platform/layout", //path - CodeNumberGenerator.AppendCode(platform.Code, CodeNumberGenerator.CreateCode(2)), //code - "/platform/layout/index", //component - "布局", //displayName - "", //redirect - "布局", //description - platform.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "布局" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var menus = await SeedMenuAsync( - layout, //layout - data, //data - "Menu", //name - "/platform/menu", //path - CodeNumberGenerator.AppendCode(platform.Code, CodeNumberGenerator.CreateCode(3)), //code - "/platform/menu/index", //component - "菜单", //displayName - "", //redirect - "菜单", //description - platform.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "菜单" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - } - - private async Task SeedApiGatewayMenuAsync(Layout layout, Data data) - { - var apiGateway = await SeedMenuAsync( - layout, //layout - data, //data - "ApiGateway", //name - "/api-gateway", //path - CodeNumberGenerator.CreateCode(25), //code - layout.Path, //component - "网关管理", //displayName - "", //redirect - "网关管理", //description - null, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "网关管理" }, - { "icon", "ant-design:gateway-outlined" }, - { "hideTab", false }, - { "ignoreAuth", false }, - }, - new string[] { "admin" }); - var routeGroup = await SeedMenuAsync( - layout, //layout - data, //data - "RouteGroup", //name - "/api-gateway/group", //path - CodeNumberGenerator.AppendCode(apiGateway.Code, CodeNumberGenerator.CreateCode(1)), //code - "/api-gateway/group/index", //component - "路由分组", //displayName - "", //redirect - "路由分组", //description - apiGateway.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "路由分组" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var global = await SeedMenuAsync( - layout, //layout - data, //data - "GlobalConfiguration", //name - "/api-gateway/global", //path - CodeNumberGenerator.AppendCode(apiGateway.Code, CodeNumberGenerator.CreateCode(2)), //code - "/api-gateway/global/index", //component - "公共配置", //displayName - "", //redirect - "公共配置", //description - apiGateway.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "公共配置" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var route = await SeedMenuAsync( - layout, //layout - data, //data - "Route", //name - "/api-gateway/route", //path - CodeNumberGenerator.AppendCode(apiGateway.Code, CodeNumberGenerator.CreateCode(3)), //code - "/api-gateway/route/index", //component - "路由管理", //displayName - "", //redirect - "路由管理", //description - apiGateway.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "路由管理" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var aggregate = await SeedMenuAsync( - layout, //layout - data, //data - "AggregateRoute", //name - "/api-gateway/aggregate", //path - CodeNumberGenerator.AppendCode(apiGateway.Code, CodeNumberGenerator.CreateCode(4)), //code - "/api-gateway/aggregate/index", //component - "聚合路由", //displayName - "", //redirect - "聚合路由", //description - apiGateway.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "聚合路由" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - } - - private async Task SeedLocalizationMenuAsync(Layout layout, Data data) - { - var localization = await SeedMenuAsync( - layout, //layout - data, //data - "Localization", //name - "/localization", //path - CodeNumberGenerator.CreateCode(26), //code - layout.Path, //component - "本地化管理", //displayName - "", //redirect - "本地化管理", //description - null, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "本地化管理" }, - { "icon", "ant-design:translation-outlined" }, - { "hideTab", false }, - { "ignoreAuth", false }, - }, - new string[] { "admin" }); - var languages = await SeedMenuAsync( - layout, //layout - data, //data - "Languages", //name - "/localization/languages", //path - CodeNumberGenerator.AppendCode(localization.Code, CodeNumberGenerator.CreateCode(1)), //code - "/localization/languages/index", //component - "语言管理", //displayName - "", //redirect - "语言管理", //description - localization.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "语言管理" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var resources = await SeedMenuAsync( - layout, //layout - data, //data - "Resources", //name - "/localization/resources", //path - CodeNumberGenerator.AppendCode(localization.Code, CodeNumberGenerator.CreateCode(2)), //code - "/localization/resources/index", //component - "资源管理", //displayName - "", //redirect - "资源管理", //description - localization.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "资源管理" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var texts = await SeedMenuAsync( - layout, //layout - data, //data - "Texts", //name - "/localization/texts", //path - CodeNumberGenerator.AppendCode(localization.Code, CodeNumberGenerator.CreateCode(3)), //code - "/localization/texts/index", //component - "文档管理", //displayName - "", //redirect - "文档管理", //description - localization.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "文档管理" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - } - - private async Task SeedOssManagementMenuAsync(Layout layout, Data data) - { - var oss = await SeedMenuAsync( - layout, //layout - data, //data - "OssManagement", //name - "/oss", //path - CodeNumberGenerator.CreateCode(27), //code - layout.Path, //component - "对象存储", //displayName - "", //redirect - "对象存储", //description - null, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "对象存储" }, - { "icon", "ant-design:file-twotone" }, - { "hideTab", false }, - { "ignoreAuth", false }, - }, - new string[] { "admin" }); - var containers = await SeedMenuAsync( - layout, //layout - data, //data - "Containers", //name - "/oss/containers", //path - CodeNumberGenerator.AppendCode(oss.Code, CodeNumberGenerator.CreateCode(1)), //code - "/oss-management/containers/index", //component - "容器管理", //displayName - "", //redirect - "容器管理", //description - oss.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "容器管理" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - var objects = await SeedMenuAsync( - layout, //layout - data, //data - "Objects", //name - "/oss/objects", //path - CodeNumberGenerator.AppendCode(oss.Code, CodeNumberGenerator.CreateCode(2)), //code - "/oss-management/objects/index", //component - "文件管理", //displayName - "", //redirect - "文件管理", //description - oss.Id, //parentId - layout.TenantId, //tenantId - new Dictionary() //meta - { - { "title", "文件管理" }, - { "icon", "" }, - { "hideTab", false }, - }, - new string[] { "admin" }); - } - - private async Task SeedMenuAsync( - Layout layout, - Data data, - string name, - string path, - string code, - string component, - string displayName, - string redirect = "", - string description = "", - Guid? parentId = null, - Guid? tenantId = null, - Dictionary meta = null, - string[] roles = null, - Guid[] users = null, - bool isPublic = false - ) - { - var menu = await RouteDataSeeder.SeedMenuAsync( - layout, - name, - path, - code, - component, - displayName, - redirect, - description, - parentId, - tenantId, - isPublic - ); - foreach (var item in data.Items) - { - menu.SetProperty(item.Name, item.DefaultValue); - } - if (meta != null) - { - foreach (var item in meta) - { - menu.SetProperty(item.Key, item.Value); - } - } - - if (roles != null) - { - foreach (var role in roles) - { - await RouteDataSeeder.SeedRoleMenuAsync(role, menu, tenantId); - } - } - - if (users != null) - { - foreach (var user in users) - { - await RouteDataSeeder.SeedUserMenuAsync(user, menu, tenantId); - } - } - - return menu; - } - } -} diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj index d56bba768..290e2effb 100644 --- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj +++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj @@ -69,6 +69,7 @@ +