Browse Source

Merge pull request #159 from colinin/3.3

Support Dynamic Menus
pull/177/head
cKey 5 years ago
committed by GitHub
parent
commit
fda92eba79
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 51
      aspnet-core/LINGYUN.MicroService.Common.sln
  2. 20
      aspnet-core/database/ApiGateway-Init-SqlServer.sql
  3. 155
      aspnet-core/database/ApiGateway-Init.sql
  4. 8
      aspnet-core/modules/common/LINGYUN.Abp.Core/AbpCommonModule.cs
  5. 30
      aspnet-core/modules/common/LINGYUN.Abp.Core/DynamicOptionsProvider.cs
  6. 8
      aspnet-core/modules/common/LINGYUN.Abp.Core/IOptionsProvider.cs
  7. 15
      aspnet-core/modules/common/LINGYUN.Abp.Core/LINGYUN.Abp.Core.csproj
  8. 4
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN.Platform.Application.Contracts.csproj
  9. 9
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataCreateDto.cs
  10. 19
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataCreateOrUpdateDto.cs
  11. 21
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataDto.cs
  12. 13
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataItemCreateDto.cs
  13. 38
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataItemCreateOrUpdateDto.cs
  14. 20
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataItemDto.cs
  15. 8
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataItemUpdateDto.cs
  16. 7
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataUpdateDto.cs
  17. 12
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/GetDataByNameInput.cs
  18. 9
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/GetDataListInput.cs
  19. 24
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/IDataAppService.cs
  20. 13
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Layouts/Dto/GetLayoutListInput.cs
  21. 9
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Layouts/Dto/LayoutCreateDto.cs
  22. 29
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Layouts/Dto/LayoutCreateOrUpdateDto.cs
  23. 17
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Layouts/Dto/LayoutDto.cs
  24. 6
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Layouts/Dto/LayoutUpdateDto.cs
  25. 18
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Layouts/ILayoutAppService.cs
  26. 11
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Localization/ApplicationContracts/en.json
  27. 11
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Localization/ApplicationContracts/zh-Hans.json
  28. 7
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/GetMenuInput.cs
  29. 13
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuCreateDto.cs
  30. 36
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuCreateOrUpdateDto.cs
  31. 32
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuDto.cs
  32. 20
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuGetAllInput.cs
  33. 13
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuGetByRoleInput.cs
  34. 15
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuGetByUserInput.cs
  35. 18
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuGetListInput.cs
  36. 21
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuItemDto.cs
  37. 6
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuUpdateDto.cs
  38. 16
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/RoleMenuInput.cs
  39. 15
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/UserMenuInput.cs
  40. 28
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/IMenuAppService.cs
  41. 19
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Permissions/PlatformPermissionDefinitionProvider.cs
  42. 41
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Permissions/PlatformPermissions.cs
  43. 6
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/PlatformApplicationContractModule.cs
  44. 7
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/PlatformRemoteServiceConsts.cs
  45. 34
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Routes/Dto/RouteDto.cs
  46. 14
      aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/AppPlatformApplicationMappingProfile.cs
  47. 191
      aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/Datas/DataAppService.cs
  48. 124
      aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/Layouts/LayoutAppService.cs
  49. 238
      aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/Menus/MenuAppService.cs
  50. 24
      aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/PlatformApplicationMappingProfile.cs
  51. 8
      aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/PlatformApplicationModule.cs
  52. 4
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN.Platform.Domain.Shared.csproj
  53. 29
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Datas/DataConsts.cs
  54. 29
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Datas/DataItemConsts.cs
  55. 13
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Datas/ValueType.cs
  56. 47
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Localization/Resources/en.json
  57. 47
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Localization/Resources/zh-Hans.json
  58. 21
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Menus/MenuConsts.cs
  59. 14
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/PlatformConsts.cs
  60. 6
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/PlatformDomainSharedModule.cs
  61. 24
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/PlatformErrorCodes.cs
  62. 6
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/PlatformType.cs
  63. 8
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Routes/RouteConsts.cs
  64. 7
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Routes/RouteEto.cs
  65. 121
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/Data.cs
  66. 50
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/DataDictionaryDataSeeder.cs
  67. 90
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/DataItem.cs
  68. 105
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/DataItemMappingOptions.cs
  69. 18
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/IDataDictionaryDataSeeder.cs
  70. 34
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/IDataRepository.cs
  71. 38
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Layouts/ILayoutRepository.cs
  72. 39
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Layouts/Layout.cs
  73. 113
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/IMenuRepository.cs
  74. 28
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/IRoleMenuRepository.cs
  75. 28
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/IUserMenuRepository.cs
  76. 67
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/Menu.cs
  77. 191
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/MenuManager.cs
  78. 35
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/RoleMenu.cs
  79. 35
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/UserMenu.cs
  80. 768
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/PlatformDataSeedContributor.cs
  81. 2
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/PlatformDbProperties.cs
  82. 6
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/PlatformDomainMappingProfile.cs
  83. 22
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/PlatformDomainModule.cs
  84. 50
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/IRouteDataSeeder.cs
  85. 78
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/IRouteRepository.cs
  86. 31
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/RoleRoute.cs
  87. 186
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/Route.cs
  88. 150
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/RouteDataSeeder.cs
  89. 139
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/RouteManager.cs
  90. 29
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/UserRoute.cs
  91. 94
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Utils/CodeNumberGenerator.cs
  92. 79
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/Datas/EfCoreDataRepository.cs
  93. 143
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/AppPlatformDbContextModelBuilderExtensions.cs
  94. 10
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/IPlatformDbContext.cs
  95. 10
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/PlatformDbContext.cs
  96. 249
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/PlatformDbContextModelBuilderExtensions.cs
  97. 34
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/PlatformEfCoreQueryableExtensions.cs
  98. 14
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/PlatformEntityFrameworkCoreModule.cs
  99. 4
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/PlatformModelBuilderConfigurationOptions.cs
  100. 74
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/Layouts/EfCoreLayoutRepository.cs

51
aspnet-core/LINGYUN.MicroService.Common.sln

@ -59,10 +59,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wechat", "wechat", "{22C614
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat", "modules\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj", "{865D5508-63CD-4D44-9F5B-AE5CD4A43D08}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.WeChat.WeApp", "modules\wechat\LINGYUN.Abp.Notifications.WeChat\LINGYUN.Abp.Notifications.WeChat.WeApp.csproj", "{076B511E-39C5-4C91-BE8D-CA666CCCEA46}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.Authorization", "modules\wechat\LINGYUN.Abp.WeChat.Authorization\LINGYUN.Abp.WeChat.Authorization.csproj", "{BCB7E04B-4A60-4596-8051-8ABC08444CAF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Settings", "modules\common\LINGYUN.Abp.Settings\LINGYUN.Abp.Settings.csproj", "{ECAA4B82-A240-4747-888C-FACD8634D389}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Sms.Aliyun", "modules\common\LINGYUN.Abp.Sms.Aliyun\LINGYUN.Abp.Sms.Aliyun.csproj", "{8AF8FD6B-634F-41FA-B421-A4ACFD159FE0}"
@ -89,7 +85,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MultiTenancy.Db
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MultiTenancy.RemoteService", "modules\tenants\LINGYUN.Abp.MultiTenancy.RemoteService\LINGYUN.Abp.MultiTenancy.RemoteService.csproj", "{21C0A260-BC14-4A8F-9299-A9EE58682B96}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Notifications.Sms", "modules\common\LINGYUN.Abp.Notifications.Sms\LINGYUN.Abp.Notifications.Sms.csproj", "{15FC0C39-A604-491F-91F6-BD44167FC5F6}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Sms", "modules\common\LINGYUN.Abp.Notifications.Sms\LINGYUN.Abp.Notifications.Sms.csproj", "{15FC0C39-A604-491F-91F6-BD44167FC5F6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.MiniProgram", "modules\wechat\LINGYUN.Abp.WeChat.MiniProgram\LINGYUN.Abp.WeChat.MiniProgram.csproj", "{9E59B1DB-E0D5-485D-BDA0-B6C31E1358A8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.Official", "modules\wechat\LINGYUN.Abp.WeChat.Official\LINGYUN.Abp.WeChat.Official.csproj", "{16942653-B746-4917-B3BF-464C99F8832F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.SettingManagement", "modules\wechat\LINGYUN.Abp.WeChat.SettingManagement\LINGYUN.Abp.WeChat.SettingManagement.csproj", "{D0717513-2CEE-4AD5-A1DA-A08EA5DE6DD6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.WeChat.MiniProgram", "modules\wechat\LINGYUN.Abp.Notifications.WeChat.MiniProgram\LINGYUN.Abp.Notifications.WeChat.MiniProgram.csproj", "{D119C919-230B-4614-9A06-98586635DBFC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Core", "modules\common\LINGYUN.Abp.Core\LINGYUN.Abp.Core.csproj", "{A7A28D6C-6EDB-4615-8899-7DE1D435B750}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -197,14 +203,6 @@ Global
{865D5508-63CD-4D44-9F5B-AE5CD4A43D08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{865D5508-63CD-4D44-9F5B-AE5CD4A43D08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{865D5508-63CD-4D44-9F5B-AE5CD4A43D08}.Release|Any CPU.Build.0 = Release|Any CPU
{076B511E-39C5-4C91-BE8D-CA666CCCEA46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{076B511E-39C5-4C91-BE8D-CA666CCCEA46}.Debug|Any CPU.Build.0 = Debug|Any CPU
{076B511E-39C5-4C91-BE8D-CA666CCCEA46}.Release|Any CPU.ActiveCfg = Release|Any CPU
{076B511E-39C5-4C91-BE8D-CA666CCCEA46}.Release|Any CPU.Build.0 = Release|Any CPU
{BCB7E04B-4A60-4596-8051-8ABC08444CAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BCB7E04B-4A60-4596-8051-8ABC08444CAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BCB7E04B-4A60-4596-8051-8ABC08444CAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BCB7E04B-4A60-4596-8051-8ABC08444CAF}.Release|Any CPU.Build.0 = Release|Any CPU
{ECAA4B82-A240-4747-888C-FACD8634D389}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ECAA4B82-A240-4747-888C-FACD8634D389}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ECAA4B82-A240-4747-888C-FACD8634D389}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -237,6 +235,26 @@ Global
{15FC0C39-A604-491F-91F6-BD44167FC5F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{15FC0C39-A604-491F-91F6-BD44167FC5F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{15FC0C39-A604-491F-91F6-BD44167FC5F6}.Release|Any CPU.Build.0 = Release|Any CPU
{9E59B1DB-E0D5-485D-BDA0-B6C31E1358A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E59B1DB-E0D5-485D-BDA0-B6C31E1358A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E59B1DB-E0D5-485D-BDA0-B6C31E1358A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E59B1DB-E0D5-485D-BDA0-B6C31E1358A8}.Release|Any CPU.Build.0 = Release|Any CPU
{16942653-B746-4917-B3BF-464C99F8832F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16942653-B746-4917-B3BF-464C99F8832F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16942653-B746-4917-B3BF-464C99F8832F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16942653-B746-4917-B3BF-464C99F8832F}.Release|Any CPU.Build.0 = Release|Any CPU
{D0717513-2CEE-4AD5-A1DA-A08EA5DE6DD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D0717513-2CEE-4AD5-A1DA-A08EA5DE6DD6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D0717513-2CEE-4AD5-A1DA-A08EA5DE6DD6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D0717513-2CEE-4AD5-A1DA-A08EA5DE6DD6}.Release|Any CPU.Build.0 = Release|Any CPU
{D119C919-230B-4614-9A06-98586635DBFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D119C919-230B-4614-9A06-98586635DBFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D119C919-230B-4614-9A06-98586635DBFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D119C919-230B-4614-9A06-98586635DBFC}.Release|Any CPU.Build.0 = Release|Any CPU
{A7A28D6C-6EDB-4615-8899-7DE1D435B750}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7A28D6C-6EDB-4615-8899-7DE1D435B750}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7A28D6C-6EDB-4615-8899-7DE1D435B750}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7A28D6C-6EDB-4615-8899-7DE1D435B750}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -269,8 +287,6 @@ Global
{B31CEE79-45F6-4BB9-9EEB-08843C324B37} = {B91F26C5-B148-4094-B5F1-71E5F945DBED}
{22C61434-D29A-4376-AD56-F5089F3E617A} = {02EA4E78-5891-43BC-944F-3E52FEE032E4}
{865D5508-63CD-4D44-9F5B-AE5CD4A43D08} = {22C61434-D29A-4376-AD56-F5089F3E617A}
{076B511E-39C5-4C91-BE8D-CA666CCCEA46} = {22C61434-D29A-4376-AD56-F5089F3E617A}
{BCB7E04B-4A60-4596-8051-8ABC08444CAF} = {22C61434-D29A-4376-AD56-F5089F3E617A}
{ECAA4B82-A240-4747-888C-FACD8634D389} = {086BE5BE-8594-4DA7-8819-935FEF76DABD}
{8AF8FD6B-634F-41FA-B421-A4ACFD159FE0} = {7F18BCA5-35BD-41FB-8EFF-801B56E5E414}
{7F18BCA5-35BD-41FB-8EFF-801B56E5E414} = {02EA4E78-5891-43BC-944F-3E52FEE032E4}
@ -285,6 +301,11 @@ Global
{BD0A1F2D-7667-45F8-872D-D41F36384163} = {38E21687-5F19-42C9-9D11-4B1D2EF64EDB}
{21C0A260-BC14-4A8F-9299-A9EE58682B96} = {38E21687-5F19-42C9-9D11-4B1D2EF64EDB}
{15FC0C39-A604-491F-91F6-BD44167FC5F6} = {B91F26C5-B148-4094-B5F1-71E5F945DBED}
{9E59B1DB-E0D5-485D-BDA0-B6C31E1358A8} = {22C61434-D29A-4376-AD56-F5089F3E617A}
{16942653-B746-4917-B3BF-464C99F8832F} = {22C61434-D29A-4376-AD56-F5089F3E617A}
{D0717513-2CEE-4AD5-A1DA-A08EA5DE6DD6} = {22C61434-D29A-4376-AD56-F5089F3E617A}
{D119C919-230B-4614-9A06-98586635DBFC} = {22C61434-D29A-4376-AD56-F5089F3E617A}
{A7A28D6C-6EDB-4615-8899-7DE1D435B750} = {086BE5BE-8594-4DA7-8819-935FEF76DABD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {06C707C6-02C0-411A-AD3B-2D0E13787CB8}

20
aspnet-core/database/ApiGateway-Init-SqlServer.sql

File diff suppressed because one or more lines are too long

155
aspnet-core/database/ApiGateway-Init.sql

@ -11,7 +11,7 @@
Target Server Version : 80020
File Encoding : 65001
Date: 20/11/2020 17:35:45
Date: 21/12/2020 18:32:50
*/
SET NAMES utf8mb4;
@ -93,7 +93,7 @@ CREATE TABLE `appapigatewayauthoptions` (
PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `IX_AppApiGatewayAuthOptions_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayAuthOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 160 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB AUTO_INCREMENT = 176 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of appapigatewayauthoptions
@ -223,6 +223,22 @@ INSERT INTO `appapigatewayauthoptions` VALUES (156, 1329706860249804800, '', '')
INSERT INTO `appapigatewayauthoptions` VALUES (157, 1329707002411544576, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (158, 1329708512277098496, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (159, 1329708625917571072, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (160, 1335049839287357440, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (161, 1335050034221830144, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (162, 1335050145899368448, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (163, 1335050283434790912, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (164, 1335050381770248192, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (165, 1335050520941449216, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (166, 1335050615829188608, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (167, 1335111798720450560, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (168, 1335118541370314752, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (169, 1335118660417245184, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (170, 1335118782727344128, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (171, 1335118903200337920, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (172, 1336230645078921216, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (173, 1337314809113722880, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (174, 1337314938973569024, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (175, 1340961907637243904, '', '');
-- ----------------------------
-- Table structure for appapigatewaybalanceroptions
@ -240,7 +256,7 @@ CREATE TABLE `appapigatewaybalanceroptions` (
UNIQUE INDEX `IX_AppApiGatewayBalancerOptions_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayBalancerOptions_AppApiGatewayGlobalConfiguratio~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT `FK_AppApiGatewayBalancerOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 163 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB AUTO_INCREMENT = 179 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of appapigatewaybalanceroptions
@ -371,6 +387,22 @@ INSERT INTO `appapigatewaybalanceroptions` VALUES (159, NULL, 132970686024980480
INSERT INTO `appapigatewaybalanceroptions` VALUES (160, NULL, 1329707002411544576, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (161, NULL, 1329708512277098496, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (162, NULL, 1329708625917571072, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (163, NULL, 1335049839287357440, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (164, NULL, 1335050034221830144, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (165, NULL, 1335050145899368448, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (166, NULL, 1335050283434790912, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (167, NULL, 1335050381770248192, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (168, NULL, 1335050520941449216, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (169, NULL, 1335050615829188608, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (170, NULL, 1335111798720450560, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (171, NULL, 1335118541370314752, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (172, NULL, 1335118660417245184, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (173, NULL, 1335118782727344128, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (174, NULL, 1335118903200337920, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (175, NULL, 1336230645078921216, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (176, NULL, 1337314809113722880, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (177, NULL, 1337314938973569024, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (178, NULL, 1340961907637243904, '', '', 0);
-- ----------------------------
-- Table structure for appapigatewaycacheoptions
@ -384,7 +416,7 @@ CREATE TABLE `appapigatewaycacheoptions` (
PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `IX_AppApiGatewayCacheOptions_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayCacheOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 160 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB AUTO_INCREMENT = 176 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of appapigatewaycacheoptions
@ -514,6 +546,22 @@ INSERT INTO `appapigatewaycacheoptions` VALUES (156, 1329706860249804800, 0, '')
INSERT INTO `appapigatewaycacheoptions` VALUES (157, 1329707002411544576, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (158, 1329708512277098496, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (159, 1329708625917571072, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (160, 1335049839287357440, NULL, NULL);
INSERT INTO `appapigatewaycacheoptions` VALUES (161, 1335050034221830144, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (162, 1335050145899368448, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (163, 1335050283434790912, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (164, 1335050381770248192, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (165, 1335050520941449216, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (166, 1335050615829188608, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (167, 1335111798720450560, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (168, 1335118541370314752, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (169, 1335118660417245184, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (170, 1335118782727344128, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (171, 1335118903200337920, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (172, 1336230645078921216, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (173, 1337314809113722880, NULL, NULL);
INSERT INTO `appapigatewaycacheoptions` VALUES (174, 1337314938973569024, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (175, 1340961907637243904, 0, '');
-- ----------------------------
-- Table structure for appapigatewaydiscovery
@ -623,7 +671,7 @@ CREATE TABLE `appapigatewayhttpoptions` (
UNIQUE INDEX `IX_AppApiGatewayHttpOptions_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayHttpOptions_AppApiGatewayGlobalConfiguration_It~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT `FK_AppApiGatewayHttpOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 163 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB AUTO_INCREMENT = 179 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of appapigatewayhttpoptions
@ -754,6 +802,22 @@ INSERT INTO `appapigatewayhttpoptions` VALUES (159, NULL, 1329706860249804800, 0
INSERT INTO `appapigatewayhttpoptions` VALUES (160, NULL, 1329707002411544576, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (161, NULL, 1329708512277098496, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (162, NULL, 1329708625917571072, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (163, NULL, 1335049839287357440, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (164, NULL, 1335050034221830144, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (165, NULL, 1335050145899368448, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (166, NULL, 1335050283434790912, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (167, NULL, 1335050381770248192, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (168, NULL, 1335050520941449216, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (169, NULL, 1335050615829188608, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (170, NULL, 1335111798720450560, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (171, NULL, 1335118541370314752, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (172, NULL, 1335118660417245184, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (173, NULL, 1335118782727344128, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (174, NULL, 1335118903200337920, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (175, NULL, 1336230645078921216, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (176, NULL, 1337314809113722880, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (177, NULL, 1337314938973569024, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (178, NULL, 1340961907637243904, 0, 0, 0, 0, 0);
-- ----------------------------
-- Table structure for appapigatewayqosoptions
@ -771,7 +835,7 @@ CREATE TABLE `appapigatewayqosoptions` (
UNIQUE INDEX `IX_AppApiGatewayQoSOptions_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayQoSOptions_AppApiGatewayGlobalConfiguration_Ite~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT `FK_AppApiGatewayQoSOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 163 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB AUTO_INCREMENT = 179 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of appapigatewayqosoptions
@ -902,6 +966,22 @@ INSERT INTO `appapigatewayqosoptions` VALUES (159, NULL, 1329706860249804800, 50
INSERT INTO `appapigatewayqosoptions` VALUES (160, NULL, 1329707002411544576, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (161, NULL, 1329708512277098496, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (162, NULL, 1329708625917571072, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (163, NULL, 1335049839287357440, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (164, NULL, 1335050034221830144, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (165, NULL, 1335050145899368448, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (166, NULL, 1335050283434790912, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (167, NULL, 1335050381770248192, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (168, NULL, 1335050520941449216, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (169, NULL, 1335050615829188608, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (170, NULL, 1335111798720450560, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (171, NULL, 1335118541370314752, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (172, NULL, 1335118660417245184, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (173, NULL, 1335118782727344128, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (174, NULL, 1335118903200337920, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (175, NULL, 1336230645078921216, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (176, NULL, 1337314809113722880, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (177, NULL, 1337314938973569024, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (178, NULL, 1340961907637243904, 50, 60000, 30000);
-- ----------------------------
-- Table structure for appapigatewayratelimitoptions
@ -943,7 +1023,7 @@ CREATE TABLE `appapigatewayratelimitrule` (
UNIQUE INDEX `IX_AppApiGatewayRateLimitRule_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayRateLimitRule_AppApiGatewayDynamicReRoute_Dynam~` FOREIGN KEY (`DynamicReRouteId`) REFERENCES `appapigatewaydynamicreroute` (`DynamicReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT `FK_AppApiGatewayRateLimitRule_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 160 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB AUTO_INCREMENT = 176 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of appapigatewayratelimitrule
@ -1073,6 +1153,22 @@ INSERT INTO `appapigatewayratelimitrule` VALUES (156, 1329706860249804800, NULL,
INSERT INTO `appapigatewayratelimitrule` VALUES (157, 1329707002411544576, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (158, 1329708512277098496, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (159, 1329708625917571072, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (160, 1335049839287357440, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (161, 1335050034221830144, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (162, 1335050145899368448, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (163, 1335050283434790912, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (164, 1335050381770248192, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (165, 1335050520941449216, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (166, 1335050615829188608, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (167, 1335111798720450560, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (168, 1335118541370314752, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (169, 1335118660417245184, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (170, 1335118782727344128, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (171, 1335118903200337920, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (172, 1336230645078921216, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (173, 1337314809113722880, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (174, 1337314938973569024, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (175, 1340961907637243904, NULL, '', 0, NULL, NULL, NULL);
-- ----------------------------
-- Table structure for appapigatewayreroute
@ -1112,7 +1208,7 @@ CREATE TABLE `appapigatewayreroute` (
PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `AK_AppApiGatewayReRoute_ReRouteId`(`ReRouteId`) USING BTREE,
UNIQUE INDEX `IX_AppApiGatewayReRoute_AppId_DownstreamPathTemplate_UpstreamPa~`(`AppId`, `DownstreamPathTemplate`, `UpstreamPathTemplate`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 167 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB AUTO_INCREMENT = 183 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of appapigatewayreroute
@ -1242,6 +1338,22 @@ INSERT INTO `appapigatewayreroute` VALUES (163, '{}', '1d586107d7e240b3bfc14c8ca
INSERT INTO `appapigatewayreroute` VALUES (164, '{}', 'bd9b34dd564f405bb3a063d6a719ce6e', 1329707002411544576, '【微信管理】- 微信租户配置', '/api/setting-management/wechat/by-current-tenant', '', '', '/api/setting-management/wechat/by-current-tenant', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30010,', '', '', 'wechat-setting-current-tenant', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (165, '{}', 'e9847659244b47dc80101b1c3f4edb31', 1329708512277098496, '【后台管理】- 变更全局设置', '/api/setting-management/settings/change-global', '', '', '/api/setting-management/settings/change-global', 'PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30010,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (166, '{}', '94c3692dea394b39ac0cc19f60fc1964', 1329708625917571072, '【后台管理】- 变更当前租户设置', '/api/setting-management/settings/change-current-tenant', '', '', '/api/setting-management/settings/change-current-tenant', 'PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30010,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (167, '{}', '626efeddcc0a474aa5e472b6089ca6fe', 1335049839287357440, '【平台服务】- 菜单管理', '/api/platform/menus', '', '', '/api/platform/menus', 'GET,POST,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (168, '{}', 'e4b4acf5f7dd4015828bdcd735424937', 1335050034221830144, '【平台服务】- 管理菜单', '/api/platform/menus/{id}', '', '', '/api/platform/menus/{id}', 'GET,PUT,DELETE,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (169, '{}', 'bbdb31a7eaba4bf7bead6a7e1151872c', 1335050145899368448, '【平台服务】- 获取当前用户菜单', '/api/platform/menus/by-current-user', '', '', '/api/platform/menus/by-current-user', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (170, '{}', '56a6d15682ba489aa46296cd8235cf81', 1335050283434790912, '【平台服务】- 管理用户菜单', '/api/platform/menus/by-user', '', '', '/api/platform/menus/by-user', 'GET,PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (171, '{}', '484dc97d5f4843fc85679c1faf1488bf', 1335050381770248192, '【平台服务】- 获取用户菜单', '/api/platform/menus/by-user/{userId}/{platformType}', '', '', '/api/platform/menus/by-user/{userId}/{platformType}', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (172, '{}', '63b34bbe4d3b41f397432aa12e73a40d', 1335050520941449216, '【平台服务】- 管理角色菜单', '/api/platform/menus/by-role', '', '', '/api/platform/menus/by-role', 'GET,PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (173, '{}', 'c858522741c941bf838aef7eba34b213', 1335050615829188608, '【平台服务】- 获取角色菜单', '/api/platform/menus/by-role/{role}/{platformType}', '', '', '/api/platform/menus/by-role/{role}/{platformType}', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (174, '{}', 'da02cbd7a46746f288bb98d40af03a21', 1335111798720450560, '【平台服务】- 获取所有数据字典', '/api/platform/datas/all', '', '', '/api/platform/datas/all', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (175, '{}', '6c6096b6593c47398d59f73ab62e54a3', 1335118541370314752, '【平台服务】- 数据字典', '/api/platform/datas', '', '', '/api/platform/datas', 'GET,POST,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (176, '{}', '5efb1b49a1cc4d34a3e338b9e83c12c7', 1335118660417245184, '【平台服务】- 管理数据字典', '/api/platform/datas/{id}', '', '', '/api/platform/datas/{id}', 'GET,PUT,DELETE,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (177, '{}', '00bd2892c6574942bda538aa9d3513cd', 1335118782727344128, '【平台服务】- 增加数据字典项目', '/api/platform/datas/{id}/items', '', '', '/api/platform/datas/{id}/items', 'POST,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (178, '{}', '9fae5da5d4634eaab7a59d643a8248a7', 1335118903200337920, '【平台服务】- 管理数据字典项目', '/api/platform/datas/{id}/items/{name}', '', '', '/api/platform/datas/{id}/items/{name}', 'DELETE,PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (179, '{}', '70d6120e560f41c3879ec4549636cdb8', 1336230645078921216, '【平台服务】- 获取所有菜单', '/api/platform/menus/all', '', '', '/api/platform/menus/all', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (180, '{}', 'c67549cd6cd246f08d9f6ce93c906c21', 1337314809113722880, '【平台服务】- 布局', '/api/platform/layouts', '', '', '/api/platform/layouts', 'GET,POST,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (181, '{}', 'bacca946a092434cb2ee5994c88f2c33', 1337314938973569024, '【平台服务】- 管理布局', '/api/platform/layouts/{id}', '', '', '/api/platform/layouts/{id}', 'GET,DELETE,PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (182, '{}', '741fdd4cc05a4025a9073a2e1ab9d5ea', 1340961907637243904, '【平台服务】- 获取所有布局', '/api/platform/layouts/all', '', '', '/api/platform/layouts/all', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
-- ----------------------------
-- Table structure for appapigatewayroutegroup
@ -1285,7 +1397,7 @@ CREATE TABLE `appapigatewaysecurityoptions` (
PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `IX_AppApiGatewaySecurityOptions_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewaySecurityOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 160 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB AUTO_INCREMENT = 176 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of appapigatewaysecurityoptions
@ -1415,6 +1527,22 @@ INSERT INTO `appapigatewaysecurityoptions` VALUES (156, 1329706860249804800, '',
INSERT INTO `appapigatewaysecurityoptions` VALUES (157, 1329707002411544576, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (158, 1329708512277098496, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (159, 1329708625917571072, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (160, 1335049839287357440, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (161, 1335050034221830144, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (162, 1335050145899368448, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (163, 1335050283434790912, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (164, 1335050381770248192, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (165, 1335050520941449216, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (166, 1335050615829188608, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (167, 1335111798720450560, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (168, 1335118541370314752, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (169, 1335118660417245184, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (170, 1335118782727344128, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (171, 1335118903200337920, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (172, 1336230645078921216, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (173, 1337314809113722880, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (174, 1337314938973569024, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (175, 1340961907637243904, '', '');
-- ----------------------------
-- Table structure for cap.published
@ -1436,14 +1564,7 @@ CREATE TABLE `cap.published` (
-- ----------------------------
-- Records of cap.published
-- ----------------------------
INSERT INTO `cap.published` VALUES (1329706861734588416, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1329706861734588416\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/11/20 16:43:15 +08:00\",\"cap-corr-id\":\"1329706861734588416\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-11-20T16:43:15.2508199+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-11-20 16:43:15', '2020-11-21 16:43:15', 'Succeeded');
INSERT INTO `cap.published` VALUES (1329707002549956608, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1329707002549956608\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/11/20 16:43:48 +08:00\",\"cap-corr-id\":\"1329707002549956608\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-11-20T16:43:48.825984+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-11-20 16:43:49', '2020-11-21 16:43:49', 'Succeeded');
INSERT INTO `cap.published` VALUES (1329708211352563712, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1329708211352563712\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/11/20 16:48:37 +08:00\",\"cap-corr-id\":\"1329708211352563712\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-11-20T16:48:37.0273285+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Modify\",\"Object\":\"ReRoute\"}}', 0, '2020-11-20 16:48:37', '2020-11-21 16:48:37', 'Succeeded');
INSERT INTO `cap.published` VALUES (1329708364180418560, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1329708364180418560\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/11/20 16:49:13 +08:00\",\"cap-corr-id\":\"1329708364180418560\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-11-20T16:49:13.4642334+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Modify\",\"Object\":\"ReRoute\"}}', 0, '2020-11-20 16:49:13', '2020-11-21 16:49:13', 'Succeeded');
INSERT INTO `cap.published` VALUES (1329708512352595968, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1329708512352595968\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/11/20 16:49:48 +08:00\",\"cap-corr-id\":\"1329708512352595968\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-11-20T16:49:48.7915448+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-11-20 16:49:49', '2020-11-21 16:49:49', 'Succeeded');
INSERT INTO `cap.published` VALUES (1329708626014040064, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1329708626014040064\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/11/20 16:50:15 +08:00\",\"cap-corr-id\":\"1329708626014040064\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-11-20T16:50:15.8881875+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-11-20 16:50:16', '2020-11-21 16:50:16', 'Succeeded');
INSERT INTO `cap.published` VALUES (1329708867152965632, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1329708867152965632\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/11/20 16:51:13 +08:00\",\"cap-corr-id\":\"1329708867152965632\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-11-20T16:51:13.3820372+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"AggregateRoute\"}}', 0, '2020-11-20 16:51:13', '2020-11-21 16:51:13', 'Succeeded');
INSERT INTO `cap.published` VALUES (1329709265259524096, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1329709265259524096\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/11/20 16:52:48 +08:00\",\"cap-corr-id\":\"1329709265259524096\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-11-20T16:52:48.2979878+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"AggregateRoute\"}}', 0, '2020-11-20 16:52:48', '2020-11-21 16:52:48', 'Succeeded');
INSERT INTO `cap.published` VALUES (1340961909189136384, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1340961909189136384\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/12/21 18:06:47 +08:00\",\"cap-corr-id\":\"1340961909189136384\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-12-21T18:06:47.6668667+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-12-21 18:06:48', '2020-12-22 18:06:48', 'Succeeded');
-- ----------------------------
-- Table structure for cap.received

8
aspnet-core/modules/common/LINGYUN.Abp.Core/AbpCommonModule.cs

@ -0,0 +1,8 @@
using Volo.Abp.Modularity;
namespace LINGYUN.Abp
{
public class AbpCommonModule : AbpModule
{
}
}

30
aspnet-core/modules/common/LINGYUN.Abp.Core/DynamicOptionsProvider.cs

@ -0,0 +1,30 @@
using Microsoft.Extensions.Options;
using System;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace LINGYUN.Abp
{
public class DynamicOptionsProvider<TValue> : IOptionsProvider<TValue>, ITransientDependency
where TValue : class, new()
{
public TValue Value => _lazyValueFactory.Value;
private readonly Lazy<TValue> _lazyValueFactory;
private readonly OneTimeRunner _oneTimeRunner;
public DynamicOptionsProvider(IOptions<TValue> options)
{
_oneTimeRunner = new OneTimeRunner();
_lazyValueFactory = new Lazy<TValue>(() => CreateOptions(options));
}
protected virtual TValue CreateOptions(IOptions<TValue> options)
{
// 用于简化需要在使用配置前自行调用此接口的繁复步骤
// await options.SetAsync();
// _onTimeRunner.Run(async () => await options.SetAsync());
return options.Value;
}
}
}

8
aspnet-core/modules/common/LINGYUN.Abp.Core/IOptionsProvider.cs

@ -0,0 +1,8 @@
namespace LINGYUN.Abp
{
public interface IOptionsProvider<TValue>
where TValue: class, new()
{
TValue Value { get; }
}
}

15
aspnet-core/modules/common/LINGYUN.Abp.Core/LINGYUN.Abp.Core.csproj

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>LINGYUN.Abp</RootNamespace>
<Description>Abp扩展基础库</Description>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Core" Version="3.3.0" />
</ItemGroup>
</Project>

4
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN.Platform.Application.Contracts.csproj

@ -21,10 +21,6 @@
<PackageReference Include="Volo.Abp.Ddd.Application" Version="3.3.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="LINGYUN\Platform\Routes\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Platform.Domain.Shared\LINGYUN.Platform.Domain.Shared.csproj" />
</ItemGroup>

9
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataCreateDto.cs

@ -0,0 +1,9 @@
using System;
namespace LINGYUN.Platform.Datas
{
public class DataCreateDto : DataCreateOrUpdateDto
{
public Guid? ParentId { get; set; }
}
}

19
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataCreateOrUpdateDto.cs

@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Validation;
namespace LINGYUN.Platform.Datas
{
public class DataCreateOrUpdateDto
{
[Required]
[DynamicStringLength(typeof(DataConsts), nameof(DataConsts.MaxNameLength))]
public string Name { get; set; }
[Required]
[DynamicStringLength(typeof(DataConsts), nameof(DataConsts.MaxDisplayNameLength))]
public string DisplayName { get; set; }
[DynamicStringLength(typeof(DataConsts), nameof(DataConsts.MaxDescriptionLength))]
public string Description { get; set; }
}
}

21
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataDto.cs

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Platform.Datas
{
public class DataDto : EntityDto<Guid>
{
public string Name { get; set; }
public string Code { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public Guid? ParentId { get; set; }
public List<DataItemDto> Items { get; set; } = new List<DataItemDto>();
}
}

13
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataItemCreateDto.cs

@ -0,0 +1,13 @@
using System;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Validation;
namespace LINGYUN.Platform.Datas
{
public class DataItemCreateDto : DataItemCreateOrUpdateDto
{
[Required]
[DynamicStringLength(typeof(DataItemConsts), nameof(DataItemConsts.MaxNameLength))]
public string Name { get; set; }
}
}

38
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataItemCreateOrUpdateDto.cs

@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Validation;
using System;
using Microsoft.Extensions.DependencyInjection;
using LINGYUN.Platform.Localization;
using Microsoft.Extensions.Localization;
namespace LINGYUN.Platform.Datas
{
public class DataItemCreateOrUpdateDto : IValidatableObject
{
[Required]
[DynamicStringLength(typeof(DataItemConsts), nameof(DataItemConsts.MaxDisplayNameLength))]
public string DisplayName { get; set; }
[DynamicStringLength(typeof(DataItemConsts), nameof(DataItemConsts.MaxValueLength))]
public string DefaultValue { get; set; }
[DynamicStringLength(typeof(DataItemConsts), nameof(DataItemConsts.MaxDescriptionLength))]
public string Description { get; set; }
public bool AllowBeNull { get; set; }
public ValueType ValueType { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (!AllowBeNull && DefaultValue.IsNullOrWhiteSpace())
{
var localizer = validationContext.GetRequiredService<IStringLocalizer<PlatformResource>>();
yield return new ValidationResult(
localizer["The {0} field is required.", localizer["DisplayName:Value"]],
new string[] { nameof(DefaultValue) });
}
}
}
}

20
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataItemDto.cs

@ -0,0 +1,20 @@
using System;
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Platform.Datas
{
public class DataItemDto : EntityDto<Guid>
{
public string Name { get; set; }
public string DisplayName { get; set; }
public string DefaultValue { get; set; }
public string Description { get; set; }
public bool AllowBeNull { get; set; }
public ValueType ValueType { get; set; }
}
}

8
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataItemUpdateDto.cs

@ -0,0 +1,8 @@
using System;
namespace LINGYUN.Platform.Datas
{
public class DataItemUpdateDto : DataItemCreateOrUpdateDto
{
}
}

7
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataUpdateDto.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Platform.Datas
{
public class DataUpdateDto : DataCreateOrUpdateDto
{
}
}

12
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/GetDataByNameInput.cs

@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Validation;
namespace LINGYUN.Platform.Datas
{
public class GetDataByNameInput
{
[Required]
[DynamicStringLength(typeof(DataConsts), nameof(DataConsts.MaxNameLength))]
public string Name { get; set; }
}
}

9
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/GetDataListInput.cs

@ -0,0 +1,9 @@
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Platform.Datas
{
public class GetDataListInput : PagedAndSortedResultRequestDto
{
public string Filter { get; set; }
}
}

24
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/IDataAppService.cs

@ -0,0 +1,24 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace LINGYUN.Platform.Datas
{
public interface IDataAppService :
ICrudAppService<
DataDto,
Guid,
GetDataListInput,
DataCreateDto,
DataUpdateDto>
{
Task<ListResultDto<DataDto>> GetAllAsync();
Task CreateItemAsync(Guid id, DataItemCreateDto input);
Task UpdateItemAsync(Guid id, string name, DataItemUpdateDto input);
Task DeleteItemAsync(Guid id, string name);
}
}

13
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Layouts/Dto/GetLayoutListInput.cs

@ -0,0 +1,13 @@
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Platform.Layouts
{
public class GetLayoutListInput : PagedAndSortedResultRequestDto
{
public string Filter { get; set; }
public bool Reverse { get; set; }
public PlatformType? PlatformType { get; set; }
}
}

9
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Layouts/Dto/LayoutCreateDto.cs

@ -0,0 +1,9 @@
using System;
namespace LINGYUN.Platform.Layouts
{
public class LayoutCreateDto : LayoutCreateOrUpdateDto
{
public Guid DataId { get; set; }
}
}

29
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Layouts/Dto/LayoutCreateOrUpdateDto.cs

@ -0,0 +1,29 @@
using LINGYUN.Platform.Routes;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Validation;
namespace LINGYUN.Platform.Layouts
{
public class LayoutCreateOrUpdateDto
{
[Required]
[DynamicStringLength(typeof(RouteConsts), nameof(RouteConsts.MaxNameLength))]
public string Name { get; set; }
[Required]
[DynamicStringLength(typeof(RouteConsts), nameof(RouteConsts.MaxDisplayNameLength))]
public string DisplayName { get; set; }
[DynamicStringLength(typeof(RouteConsts), nameof(RouteConsts.MaxDescriptionLength))]
public string Description { get; set; }
[Required]
[DynamicStringLength(typeof(RouteConsts), nameof(RouteConsts.MaxPathLength))]
public string Path { get; set; }
[DynamicStringLength(typeof(RouteConsts), nameof(RouteConsts.MaxRedirectLength))]
public string Redirect { get; set; }
public PlatformType PlatformType { get; set; }
}
}

17
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Layouts/Dto/LayoutDto.cs

@ -0,0 +1,17 @@
using LINGYUN.Platform.Routes;
using System;
namespace LINGYUN.Platform.Layouts
{
public class LayoutDto : RouteDto
{
/// <summary>
/// 所属平台
/// </summary>
public PlatformType PlatformType { get; set; }
/// <summary>
/// 约定的Meta采用哪种数据字典,主要是约束路由必须字段的一致性
/// </summary>
public Guid DataId { get; set; }
}
}

6
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Layouts/Dto/LayoutUpdateDto.cs

@ -0,0 +1,6 @@
namespace LINGYUN.Platform.Layouts
{
public class LayoutUpdateDto : LayoutCreateOrUpdateDto
{
}
}

18
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Layouts/ILayoutAppService.cs

@ -0,0 +1,18 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace LINGYUN.Platform.Layouts
{
public interface ILayoutAppService :
ICrudAppService<
LayoutDto,
Guid,
GetLayoutListInput,
LayoutCreateDto,
LayoutUpdateDto>
{
Task<ListResultDto<LayoutDto>> GetAllListAsync();
}
}

11
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Localization/ApplicationContracts/en.json

@ -17,6 +17,15 @@
"Permission:DeleteFile": "Delete file",
"Permission:CopyFile": "Copy file",
"Permission:MoveFile": "Move file",
"Permission:DownloadFile": "Download file"
"Permission:DownloadFile": "Download file",
"Permission:DataDictionary": "Data Dictionary",
"Permission:Layout": "Layout",
"Permission:Menu": "Menu",
"Permission:Create": "Create",
"Permission:Update": "Update",
"Permission:Delete": "Delete",
"Permission:ManageItems": "Manage Items",
"Permission:ManageRoleMenus": "Manage Role Menus",
"Permission:ManageUserMenus": "Manage User Menus"
}
}

11
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Localization/ApplicationContracts/zh-Hans.json

@ -17,6 +17,15 @@
"Permission:DeleteFile": "删除文件",
"Permission:CopyFile": "复制文件",
"Permission:MoveFile": "移动文件",
"Permission:DownloadFile": "下载文件"
"Permission:DownloadFile": "下载文件",
"Permission:DataDictionary": "数据字典",
"Permission:Layout": "布局管理",
"Permission:Menu": "菜单管理",
"Permission:Create": "新增",
"Permission:Update": "新增",
"Permission:Delete": "新增",
"Permission:ManageItems": "管理项目",
"Permission:ManageRoleMenus": "管理角色菜单",
"Permission:ManageUserMenus": "管理用户菜单"
}
}

7
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/GetMenuInput.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Platform.Menus
{
public class GetMenuInput
{
public PlatformType PlatformType { get; set; }
}
}

13
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuCreateDto.cs

@ -0,0 +1,13 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Platform.Menus
{
public class MenuCreateDto : MenuCreateOrUpdateDto
{
public Guid? ParentId { get; set; }
[Required]
public Guid LayoutId { get; set; }
}
}

36
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuCreateOrUpdateDto.cs

@ -0,0 +1,36 @@
using LINGYUN.Platform.Routes;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Validation;
namespace LINGYUN.Platform.Menus
{
public class MenuCreateOrUpdateDto
{
[Required]
[DynamicStringLength(typeof(RouteConsts), nameof(RouteConsts.MaxNameLength))]
public string Name { get; set; }
[Required]
[DynamicStringLength(typeof(RouteConsts), nameof(RouteConsts.MaxDisplayNameLength))]
public string DisplayName { get; set; }
[DynamicStringLength(typeof(RouteConsts), nameof(RouteConsts.MaxDescriptionLength))]
public string Description { get; set; }
[Required]
[DynamicStringLength(typeof(RouteConsts), nameof(RouteConsts.MaxPathLength))]
public string Path { get; set; }
[DynamicStringLength(typeof(RouteConsts), nameof(RouteConsts.MaxRedirectLength))]
public string Redirect { get; set; }
[Required]
[DynamicStringLength(typeof(MenuConsts), nameof(MenuConsts.MaxComponentLength))]
public string Component { get; set; }
public bool IsPublic { get; set; }
public Dictionary<string, object> Meta { get; set; } = new Dictionary<string, object>();
}
}

32
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuDto.cs

@ -0,0 +1,32 @@
using LINGYUN.Platform.Routes;
using System;
using System.Collections.Generic;
namespace LINGYUN.Platform.Menus
{
public class MenuDto : RouteDto
{
/// <summary>
/// 菜单编号
/// </summary>
public string Code { get; set; }
/// <summary>
/// 菜单布局页
/// </summary>
public string Component { get; set; }
/// <summary>
/// 所属平台
/// </summary>
public PlatformType PlatformType { get; set; }
/// <summary>
/// 父节点
/// </summary>
public Guid? ParentId { get; set; }
/// <summary>
/// 所属布局标识
/// </summary>
public Guid LayoutId { get; set; }
public bool IsPublic { get; set; }
}
}

20
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuGetAllInput.cs

@ -0,0 +1,20 @@
using System;
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Platform.Menus
{
public class MenuGetAllInput : ISortedResultRequest
{
public PlatformType? PlatformType { get; set; }
public string Filter { get; set; }
public bool Reverse { get; set; }
public Guid? ParentId { get; set; }
public string Sorting { get; set; }
public Guid? LayoutId { get; set; }
}
}

13
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuGetByRoleInput.cs

@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Platform.Menus
{
public class MenuGetByRoleInput
{
[Required]
[StringLength(80)]
public string Role { get; set; }
public PlatformType PlatformType { get; set; }
}
}

15
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuGetByUserInput.cs

@ -0,0 +1,15 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Platform.Menus
{
public class MenuGetByUserInput
{
[Required]
public Guid UserId { get; set; }
public string[] Roles { get; set; } = new string[0];
public PlatformType PlatformType { get; set; }
}
}

18
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuGetListInput.cs

@ -0,0 +1,18 @@
using System;
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Platform.Menus
{
public class MenuGetListInput : PagedAndSortedResultRequestDto
{
public PlatformType? PlatformType { get; set; }
public string Filter { get; set; }
public bool Reverse { get; set; }
public Guid? ParentId { get; set; }
public Guid? LayoutId { get; set; }
}
}

21
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuItemDto.cs

@ -0,0 +1,21 @@
using LINGYUN.Platform.Routes;
using System.Collections.Generic;
namespace LINGYUN.Platform.Menus
{
public class MenuItemDto : RouteDto
{
/// <summary>
/// 菜单编号
/// </summary>
public string Code { get; set; }
/// <summary>
/// 菜单组件
/// </summary>
public string Component { get; set; }
/// <summary>
/// 子菜单列表
/// </summary>
public List<MenuItemDto> Children { get; set; } = new List<MenuItemDto>();
}
}

6
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/MenuUpdateDto.cs

@ -0,0 +1,6 @@
namespace LINGYUN.Platform.Menus
{
public class MenuUpdateDto : MenuCreateOrUpdateDto
{
}
}

16
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/RoleMenuInput.cs

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Platform.Menus
{
public class RoleMenuInput
{
[Required]
[StringLength(80)]
public string RoleName { get; set; }
[Required]
public List<Guid> MenuIds { get; set; } = new List<Guid>();
}
}

15
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/UserMenuInput.cs

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Platform.Menus
{
public class UserMenuInput
{
[Required]
public Guid UserId { get; set; }
[Required]
public List<Guid> MenuIds { get; set; } = new List<Guid>();
}
}

28
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/IMenuAppService.cs

@ -0,0 +1,28 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace LINGYUN.Platform.Menus
{
public interface IMenuAppService :
ICrudAppService<
MenuDto,
Guid,
MenuGetListInput,
MenuCreateDto,
MenuUpdateDto>
{
Task<ListResultDto<MenuDto>> GetAllAsync(MenuGetAllInput input);
Task<ListResultDto<MenuDto>> GetUserMenuListAsync(MenuGetByUserInput input);
Task<ListResultDto<MenuDto>> GetRoleMenuListAsync(MenuGetByRoleInput input);
Task SetUserMenusAsync(UserMenuInput input);
Task SetRoleMenusAsync(RoleMenuInput input);
Task<ListResultDto<MenuDto>> GetCurrentUserMenuListAsync(GetMenuInput input);
}
}

19
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Permissions/PlatformPermissionDefinitionProvider.cs

@ -19,6 +19,25 @@ namespace LINGYUN.Platform.Permissions
versionFile.AddChild(PlatformPermissions.AppVersion.FileManager.Delete, L("Permission:DeleteFile"));
versionFile.AddChild(PlatformPermissions.AppVersion.FileManager.Download, L("Permission:DownloadFile"));
var dataDictionary = platform.AddPermission(PlatformPermissions.DataDictionary.Default, L("Permission:DataDictionary"));
dataDictionary.AddChild(PlatformPermissions.DataDictionary.Create, L("Permission:Create"));
dataDictionary.AddChild(PlatformPermissions.DataDictionary.Update, L("Permission:Update"));
dataDictionary.AddChild(PlatformPermissions.DataDictionary.Delete, L("Permission:Delete"));
dataDictionary.AddChild(PlatformPermissions.DataDictionary.ManageItems, L("Permission:ManageItems"));
var layout = platform.AddPermission(PlatformPermissions.Layout.Default, L("Permission:Layout"));
layout.AddChild(PlatformPermissions.Layout.Create, L("Permission:Create"));
layout.AddChild(PlatformPermissions.Layout.Update, L("Permission:Update"));
layout.AddChild(PlatformPermissions.Layout.Delete, L("Permission:Delete"));
var menu = platform.AddPermission(PlatformPermissions.Menu.Default, L("Permission:Menu"));
menu.AddChild(PlatformPermissions.Menu.Create, L("Permission:Create"));
menu.AddChild(PlatformPermissions.Menu.Update, L("Permission:Update"));
menu.AddChild(PlatformPermissions.Menu.Delete, L("Permission:Delete"));
menu.AddChild(PlatformPermissions.Menu.ManageRoles, L("Permission:ManageRoleMenus"));
menu.AddChild(PlatformPermissions.Menu.ManageUsers, L("Permission:ManageUserMenus"));
// TODO: 2020-07-27 目前abp不支持对象存储管理(或者属于企业版?)需要创建一个 LINGYUN.Abp.BlobStoring 项目自行实现
//var fileSystem = platform.AddPermission(PlatformPermissions.FileSystem.Default, L("Permission:FileSystem"));

41
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Permissions/PlatformPermissions.cs

@ -2,10 +2,49 @@
namespace LINGYUN.Platform.Permissions
{
public class PlatformPermissions
public static class PlatformPermissions
{
public const string GroupName = "Platform";
public class DataDictionary
{
public const string Default = GroupName + ".DataDictionary";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
public const string ManageItems = Default + ".ManageItems";
}
public class Layout
{
public const string Default = GroupName + ".Layout";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
}
public class Menu
{
public const string Default = GroupName + ".Menu";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
public const string ManageRoles = Default + ".ManageRoles";
public const string ManageUsers = Default + ".ManageUsers";
}
// 如果abp后期提供对象存储的目录管理接口,则启用此权限
/// <summary>
/// 文件系统

6
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/AppPlatformApplicationContractModule.cs → aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/PlatformApplicationContractModule.cs

@ -5,14 +5,14 @@ using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Platform
{
[DependsOn(typeof(AppPlatformDomainSharedModule))]
public class AppPlatformApplicationContractModule : AbpModule
[DependsOn(typeof(PlatformDomainSharedModule))]
public class PlatformApplicationContractModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AppPlatformApplicationContractModule>();
options.FileSets.AddEmbedded<PlatformApplicationContractModule>();
});
Configure<AbpLocalizationOptions>(options =>

7
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/PlatformRemoteServiceConsts.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Platform
{
public static class PlatformRemoteServiceConsts
{
public const string RemoteServiceName = "Platform";
}
}

34
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Routes/Dto/RouteDto.cs

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Platform.Routes
{
public class RouteDto : EntityDto<Guid>
{
/// <summary>
/// 路径
/// </summary>
public string Path { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 显示名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 说明
/// </summary>
public string Description { get; set; }
/// <summary>
/// 重定向路径
/// </summary>
public string Redirect { get; set; }
/// <summary>
/// 路由的一些辅助元素,取决于数据字典的设计
/// </summary>
public Dictionary<string, object> Meta { get; set; }
}
}

14
aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/AppPlatformApplicationMappingProfile.cs

@ -1,14 +0,0 @@
using AutoMapper;
using LINGYUN.Platform.Versions;
namespace LINGYUN.Platform
{
public class AppPlatformApplicationMappingProfile : Profile
{
public AppPlatformApplicationMappingProfile()
{
CreateMap<VersionFile, VersionFileDto>();
CreateMap<AppVersion, VersionDto>();
}
}
}

191
aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/Datas/DataAppService.cs

@ -0,0 +1,191 @@
using LINGYUN.Platform.Permissions;
using LINGYUN.Platform.Utils;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Platform.Datas
{
[Authorize(PlatformPermissions.DataDictionary.Default)]
public class DataAppService : PlatformApplicationServiceBase, IDataAppService
{
protected IDataRepository DataRepository { get; }
public DataAppService(
IDataRepository dataRepository)
{
DataRepository = dataRepository;
}
[Authorize(PlatformPermissions.DataDictionary.Create)]
public virtual async Task<DataDto> CreateAsync(DataCreateDto input)
{
var data = await DataRepository.FindByNameAsync(input.Name);
if (data != null)
{
throw new UserFriendlyException("指定名称的数据字典已经存在!");
}
string code = string.Empty;
var children = await DataRepository.GetChildrenAsync(input.ParentId);
if (children.Any())
{
var lastChildren = children.OrderBy(x => x.Code).FirstOrDefault();
code = CodeNumberGenerator.CalculateNextCode(lastChildren.Code);
}
else
{
var parentData = input.ParentId != null
? await DataRepository.GetAsync(input.ParentId.Value)
: null;
code = CodeNumberGenerator.AppendCode(parentData?.Code, CodeNumberGenerator.CreateCode(1));
}
data = new Data(
GuidGenerator.Create(),
input.Name,
code,
input.DisplayName,
input.Description,
input.ParentId,
CurrentTenant.Id
);
data = await DataRepository.InsertAsync(data);
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<Data, DataDto>(data);
}
[Authorize(PlatformPermissions.DataDictionary.Delete)]
public virtual async Task DeleteAsync(Guid id)
{
var data = await DataRepository.GetAsync(id);
var children = await DataRepository.GetChildrenAsync(data.Id);
if (children.Any())
{
throw new UserFriendlyException("当前数据字典存在子节点,无法删除!");
}
await DataRepository.DeleteAsync(data);
}
public virtual async Task<DataDto> GetAsync(Guid id)
{
var data = await DataRepository.GetAsync(id);
return ObjectMapper.Map<Data, DataDto>(data);
}
public virtual async Task<ListResultDto<DataDto>> GetAllAsync()
{
var datas = await DataRepository.GetListAsync(includeDetails: false);
return new ListResultDto<DataDto>(
ObjectMapper.Map<List<Data>, List<DataDto>>(datas));
}
public virtual async Task<PagedResultDto<DataDto>> GetListAsync(GetDataListInput input)
{
var count = await DataRepository.GetCountAsync(input.Filter);
var datas = await DataRepository.GetPagedListAsync(
input.Filter, input.Sorting,
false, input.SkipCount, input.MaxResultCount);
return new PagedResultDto<DataDto>(count,
ObjectMapper.Map<List<Data>, List<DataDto>>(datas));
}
[Authorize(PlatformPermissions.DataDictionary.Update)]
public virtual async Task<DataDto> UpdateAsync(Guid id, DataUpdateDto input)
{
var data = await DataRepository.GetAsync(id);
if (!string.Equals(data.Name, input.Name, StringComparison.InvariantCultureIgnoreCase))
{
data.Name = input.Name;
}
if (!string.Equals(data.DisplayName, input.DisplayName, StringComparison.InvariantCultureIgnoreCase))
{
data.DisplayName = input.DisplayName;
}
if (!string.Equals(data.Description, input.Description, StringComparison.InvariantCultureIgnoreCase))
{
data.Description = input.Description;
}
data = await DataRepository.UpdateAsync(data);
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<Data, DataDto>(data);
}
[Authorize(PlatformPermissions.DataDictionary.ManageItems)]
public virtual async Task UpdateItemAsync(Guid id, string name, DataItemUpdateDto input)
{
var data = await DataRepository.GetAsync(id);
var dataItem = data.FindItem(name);
if (dataItem == null)
{
throw new UserFriendlyException($"不存在名为 {name} 的数据字典项!");
}
if (!string.Equals(dataItem.DefaultValue, input.DefaultValue, StringComparison.InvariantCultureIgnoreCase))
{
dataItem.DefaultValue = input.DefaultValue;
}
if (!string.Equals(dataItem.DisplayName, input.DisplayName, StringComparison.InvariantCultureIgnoreCase))
{
dataItem.DisplayName = input.DisplayName;
}
if (!string.Equals(dataItem.Description, input.Description, StringComparison.InvariantCultureIgnoreCase))
{
dataItem.Description = input.Description;
}
dataItem.AllowBeNull = input.AllowBeNull;
data = await DataRepository.UpdateAsync(data);
await CurrentUnitOfWork.SaveChangesAsync();
}
[Authorize(PlatformPermissions.DataDictionary.ManageItems)]
public virtual async Task CreateItemAsync(Guid id, DataItemCreateDto input)
{
var data = await DataRepository.GetAsync(id);
var dataItem = data.FindItem(input.Name);
if (dataItem != null)
{
throw new UserFriendlyException($"已经存在名为 {input.Name} 的数据字典项!");
}
data.AddItem(
GuidGenerator,
input.Name,
input.DisplayName,
input.DefaultValue,
input.ValueType,
input.Description,
input.AllowBeNull);
await DataRepository.UpdateAsync(data);
await CurrentUnitOfWork.SaveChangesAsync();
}
[Authorize(PlatformPermissions.DataDictionary.ManageItems)]
public virtual async Task DeleteItemAsync(Guid id, string name)
{
var data = await DataRepository.GetAsync(id);
data.RemoveItem(name);
await DataRepository.UpdateAsync(data);
await CurrentUnitOfWork.SaveChangesAsync();
}
}
}

124
aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/Layouts/LayoutAppService.cs

@ -0,0 +1,124 @@
using LINGYUN.Platform.Datas;
using LINGYUN.Platform.Permissions;
using LINGYUN.Platform.Routes;
using LINGYUN.Platform.Utils;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Platform.Layouts
{
[Authorize(PlatformPermissions.Layout.Default)]
public class LayoutAppService : PlatformApplicationServiceBase, ILayoutAppService
{
protected ILayoutRepository LayoutRepository { get; }
public LayoutAppService(
ILayoutRepository layoutRepository)
{
LayoutRepository = layoutRepository;
}
[Authorize(PlatformPermissions.Layout.Create)]
public virtual async Task<LayoutDto> CreateAsync(LayoutCreateDto input)
{
var layout = await LayoutRepository.FindByNameAsync(input.Name);
if (layout != null)
{
throw new UserFriendlyException($"已经存在名为 {input.Name} 的布局!");
}
layout = new Layout(
GuidGenerator.Create(),
input.Path,
input.Name,
input.DisplayName,
input.DataId,
input.PlatformType,
input.Redirect,
input.Description,
CurrentTenant.Id);
layout = await LayoutRepository.InsertAsync(layout);
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<Layout, LayoutDto>(layout);
}
[Authorize(PlatformPermissions.Layout.Delete)]
public virtual async Task DeleteAsync(Guid id)
{
var layout = await LayoutRepository.GetAsync(id);
//if (await LayoutRepository.AnyMenuAsync(layout.Id))
//{
// throw new UserFriendlyException($"不能删除存在菜单的布局!");
//}
await LayoutRepository.DeleteAsync(layout);
await CurrentUnitOfWork.SaveChangesAsync();
}
public virtual async Task<LayoutDto> GetAsync(Guid id)
{
var layout = await LayoutRepository.GetAsync(id);
return ObjectMapper.Map<Layout, LayoutDto>(layout);
}
public virtual async Task<ListResultDto<LayoutDto>> GetAllListAsync()
{
var layouts = await LayoutRepository.GetListAsync();
return new ListResultDto<LayoutDto>(
ObjectMapper.Map<List<Layout>, List<LayoutDto>>(layouts));
}
public virtual async Task<PagedResultDto<LayoutDto>> GetListAsync(GetLayoutListInput input)
{
var count = await LayoutRepository.GetCountAsync(input.PlatformType, input.Filter);
var layouts = await LayoutRepository.GetPagedListAsync(
input.PlatformType, input.Filter,
input.Sorting, input.Reverse, false,
input.SkipCount, input.MaxResultCount);
return new PagedResultDto<LayoutDto>(count,
ObjectMapper.Map<List<Layout>, List<LayoutDto>>(layouts));
}
[Authorize(PlatformPermissions.Layout.Update)]
public virtual async Task<LayoutDto> UpdateAsync(Guid id, LayoutUpdateDto input)
{
var layout = await LayoutRepository.GetAsync(id);
if (!string.Equals(layout.Name, input.Name, StringComparison.InvariantCultureIgnoreCase))
{
layout.Name = input.Name;
}
if (!string.Equals(layout.DisplayName, input.DisplayName, StringComparison.InvariantCultureIgnoreCase))
{
layout.DisplayName = input.DisplayName;
}
if (!string.Equals(layout.Description, input.Description, StringComparison.InvariantCultureIgnoreCase))
{
layout.Description = input.Description;
}
if (!string.Equals(layout.Path, input.Path, StringComparison.InvariantCultureIgnoreCase))
{
layout.Path = input.Path;
}
if (!string.Equals(layout.Redirect, input.Redirect, StringComparison.InvariantCultureIgnoreCase))
{
layout.Redirect = input.Redirect;
}
layout = await LayoutRepository.UpdateAsync(layout);
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<Layout, LayoutDto>(layout);
}
}
}

238
aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/Menus/MenuAppService.cs

@ -0,0 +1,238 @@
using LINGYUN.Platform.Datas;
using LINGYUN.Platform.Layouts;
using LINGYUN.Platform.Permissions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Data;
using Volo.Abp.Users;
namespace LINGYUN.Platform.Menus
{
[Authorize(PlatformPermissions.Menu.Default)]
public class MenuAppService : PlatformApplicationServiceBase, IMenuAppService
{
protected DataItemMappingOptions DataItemMapping { get; }
protected MenuManager MenuManager { get; }
protected IMenuRepository MenuRepository { get; }
protected IDataRepository DataRepository { get; }
protected ILayoutRepository LayoutRepository { get; }
public MenuAppService(
MenuManager menuManager,
IMenuRepository menuRepository,
IDataRepository dataRepository,
ILayoutRepository layoutRepository,
IOptions<DataItemMappingOptions> options)
{
MenuManager = menuManager;
MenuRepository = menuRepository;
DataRepository = dataRepository;
LayoutRepository = layoutRepository;
DataItemMapping = options.Value;
}
[Authorize]
public virtual async Task<ListResultDto<MenuDto>> GetCurrentUserMenuListAsync(GetMenuInput input)
{
var myMenus = await MenuRepository.GetUserMenusAsync(
CurrentUser.GetId(),
CurrentUser.Roles,
input.PlatformType);
return new ListResultDto<MenuDto>(
ObjectMapper.Map<List<Menu>, List<MenuDto>>(myMenus));
}
public virtual async Task<MenuDto> GetAsync(Guid id)
{
var menu = await MenuRepository.GetAsync(id);
return ObjectMapper.Map<Menu, MenuDto>(menu);
}
public virtual async Task<ListResultDto<MenuDto>> GetAllAsync(MenuGetAllInput input)
{
var menus = await MenuRepository.GetAllAsync(
input.Filter, input.Sorting, input.Reverse,
input.PlatformType, input.ParentId, input.LayoutId);
return new ListResultDto<MenuDto>(
ObjectMapper.Map<List<Menu>, List<MenuDto>>(menus));
}
public virtual async Task<PagedResultDto<MenuDto>> GetListAsync(MenuGetListInput input)
{
var count = await MenuRepository.GetCountAsync(input.Filter, input.PlatformType, input.ParentId, input.LayoutId);
var menus = await MenuRepository.GetListAsync(
input.Filter, input.Sorting, input.Reverse,
input.PlatformType, input.ParentId, input.LayoutId,
input.SkipCount, input.MaxResultCount);
return new PagedResultDto<MenuDto>(count,
ObjectMapper.Map<List<Menu>, List<MenuDto>>(menus));
}
[Authorize(PlatformPermissions.Menu.Create)]
public virtual async Task<MenuDto> CreateAsync(MenuCreateDto input)
{
var layout = await LayoutRepository.GetAsync(input.LayoutId);
var data = await DataRepository.GetAsync(layout.DataId);
var menu = await MenuManager.CreateAsync(
GuidGenerator.Create(),
layout.Id,
input.Path,
input.Name,
input.Component,
input.DisplayName,
input.Redirect,
input.Description,
layout.PlatformType,
input.ParentId,
CurrentTenant.Id,
input.IsPublic);
// 利用布局约定的数据字典来校验必须的路由元数据,元数据的加入是为了适配多端路由
foreach (var dataItem in data.Items)
{
if (!input.Meta.TryGetValue(dataItem.Name, out object meta))
{
if (!dataItem.AllowBeNull)
{
throw new BusinessException(PlatformErrorCodes.MenuMissingMetadata)
.WithData("Name", dataItem.DisplayName)
.WithData("DataName", data.DisplayName);
}
// 是否需要设定默认值
menu.SetProperty(dataItem.Name, dataItem.DefaultValue);
}
else
{
// 需要检查参数是否有效
menu.SetProperty(dataItem.Name, DataItemMapping.MapToString(dataItem.ValueType, meta));
}
}
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<Menu, MenuDto>(menu);
}
[Authorize(PlatformPermissions.Menu.Update)]
public virtual async Task<MenuDto> UpdateAsync(Guid id, MenuUpdateDto input)
{
var menu = await MenuRepository.GetAsync(id);
// 利用布局约定的数据字典来校验必须的路由元数据,元数据的加入是为了适配多端路由
var layout = await LayoutRepository.GetAsync(menu.LayoutId);
var data = await DataRepository.GetAsync(layout.DataId);
foreach (var dataItem in data.Items)
{
if (!input.Meta.TryGetValue(dataItem.Name, out object meta))
{
if (!dataItem.AllowBeNull)
{
throw new BusinessException(PlatformErrorCodes.MenuMissingMetadata)
.WithData("Name", dataItem.DisplayName)
.WithData("DataName", data.DisplayName);
}
// 是否需要设定默认值?
menu.SetProperty(dataItem.Name, dataItem.DefaultValue);
}
else
{
// 与现有的数据做对比
var menuMeta = menu.GetProperty(dataItem.Name);
if (menuMeta != null && menuMeta.Equals(meta))
{
continue;
}
// 需要检查参数是否有效
menu.SetProperty(dataItem.Name, DataItemMapping.MapToString(dataItem.ValueType, meta));
}
}
if (!string.Equals(menu.Name, input.Name, StringComparison.InvariantCultureIgnoreCase))
{
menu.Name = input.Name;
}
if (!string.Equals(menu.DisplayName, input.DisplayName, StringComparison.InvariantCultureIgnoreCase))
{
menu.DisplayName = input.DisplayName;
}
if (!string.Equals(menu.Description, input.Description, StringComparison.InvariantCultureIgnoreCase))
{
menu.Description = input.Description;
}
if (!string.Equals(menu.Path, input.Path, StringComparison.InvariantCultureIgnoreCase))
{
menu.Path = input.Path;
}
if (!string.Equals(menu.Redirect, input.Redirect, StringComparison.InvariantCultureIgnoreCase))
{
menu.Redirect = input.Redirect;
}
if (!string.Equals(menu.Component, input.Component, StringComparison.InvariantCultureIgnoreCase))
{
menu.Component = input.Component;
}
menu.IsPublic = input.IsPublic;
await MenuManager.UpdateAsync(menu);
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<Menu, MenuDto>(menu);
}
[Authorize(PlatformPermissions.Menu.Delete)]
public virtual async Task DeleteAsync(Guid id)
{
var childrens = await MenuRepository.GetChildrenAsync(id);
if (childrens.Any())
{
throw new BusinessException(PlatformErrorCodes.DeleteMenuHaveChildren);
}
var menu = await MenuRepository.GetAsync(id);
await MenuRepository.DeleteAsync(menu);
}
[Authorize(PlatformPermissions.Menu.ManageUsers)]
public virtual async Task<ListResultDto<MenuDto>> GetUserMenuListAsync(MenuGetByUserInput input)
{
var menus = await MenuRepository.GetUserMenusAsync(input.UserId, input.Roles, input.PlatformType);
return new ListResultDto<MenuDto>(
ObjectMapper.Map<List<Menu>, List<MenuDto>>(menus));
}
[Authorize(PlatformPermissions.Menu.ManageUsers)]
public virtual async Task SetUserMenusAsync(UserMenuInput input)
{
await MenuManager.SetUserMenusAsync(input.UserId, input.MenuIds);
}
[Authorize(PlatformPermissions.Menu.ManageRoles)]
public virtual async Task SetRoleMenusAsync(RoleMenuInput input)
{
await MenuManager.SetRoleMenusAsync(input.RoleName, input.MenuIds);
}
[Authorize(PlatformPermissions.Menu.ManageRoles)]
public virtual async Task<ListResultDto<MenuDto>> GetRoleMenuListAsync(MenuGetByRoleInput input)
{
var menus = await MenuRepository.GetRoleMenusAsync(new string[] { input.Role }, input.PlatformType);
return new ListResultDto<MenuDto>(
ObjectMapper.Map<List<Menu>, List<MenuDto>>(menus));
}
}
}

24
aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/PlatformApplicationMappingProfile.cs

@ -0,0 +1,24 @@
using AutoMapper;
using LINGYUN.Platform.Datas;
using LINGYUN.Platform.Layouts;
using LINGYUN.Platform.Menus;
using LINGYUN.Platform.Versions;
namespace LINGYUN.Platform
{
public class PlatformApplicationMappingProfile : Profile
{
public PlatformApplicationMappingProfile()
{
CreateMap<VersionFile, VersionFileDto>();
CreateMap<AppVersion, VersionDto>();
CreateMap<DataItem, DataItemDto>();
CreateMap<Data, DataDto>();
CreateMap<Menu, MenuDto>()
.ForMember(dto => dto.Meta, map => map.MapFrom(src => src.ExtraProperties));
CreateMap<Layout, LayoutDto>()
.ForMember(dto => dto.Meta, map => map.MapFrom(src => src.ExtraProperties));
}
}
}

8
aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/AppPlatformApplicationModule.cs → aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/PlatformApplicationModule.cs

@ -4,16 +4,16 @@ using Volo.Abp.Modularity;
namespace LINGYUN.Platform
{
[DependsOn(typeof(AppPlatformApplicationContractModule))]
public class AppPlatformApplicationModule : AbpModule
[DependsOn(typeof(PlatformApplicationContractModule))]
public class PlatformApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<AppPlatformApplicationModule>();
context.Services.AddAutoMapperObjectMapper<PlatformApplicationModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<AppPlatformApplicationMappingProfile>(validate: true);
options.AddProfile<PlatformApplicationMappingProfile>(validate: true);
});
}
}

4
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN.Platform.Domain.Shared.csproj

@ -21,4 +21,8 @@
<PackageReference Include="Volo.Abp.Validation" Version="3.3.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="LINGYUN\Platform\Layouts\" />
</ItemGroup>
</Project>

29
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Datas/DataConsts.cs

@ -0,0 +1,29 @@
namespace LINGYUN.Platform.Datas
{
public static class DataConsts
{
public static int MaxNameLength
{
get;
set;
} = 30;
public static int MaxCodeLength
{
get;
set;
} = 1024;
public static int MaxDisplayNameLength
{
get;
set;
} = 128;
public static int MaxDescriptionLength
{
get;
set;
} = 1024;
}
}

29
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Datas/DataItemConsts.cs

@ -0,0 +1,29 @@
namespace LINGYUN.Platform.Datas
{
public static class DataItemConsts
{
public static int MaxNameLength
{
get;
set;
} = 30;
public static int MaxValueLength
{
get;
set;
} = 128;
public static int MaxDisplayNameLength
{
get;
set;
} = 128;
public static int MaxDescriptionLength
{
get;
set;
} = 1024;
}
}

13
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Datas/ValueType.cs

@ -0,0 +1,13 @@
namespace LINGYUN.Platform.Datas
{
public enum ValueType
{
String = 0,
Numeic = 1,
Boolean = 2,
Date = 3,
DateTime = 4,
Array = 5
}
}

47
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Localization/Resources/en.json

@ -1,12 +1,55 @@
{
"culture": "en",
"texts": {
"Platform.VersionFile:404": "File not found, name: {FileName}, version:{FileVersion}!",
"Platform:01404": "File not found, name: {FileName}, version:{FileVersion}!",
"Platform:02001": "The same menu exists in the sibling directory: {Name}!",
"Platform:02002": "You are not allowed to delete menu nodes when there are other submenus!",
"Platform:02003": "The menu level has reached the specified maximum: {Depth}!",
"Platform:02101": "The menu metadata is missing the necessary element :{Name}, which is defined in the data dictionary :{DataName}!",
"Platform:03001": "The metadata format does not match!",
"UploadFileSizeBeyondLimit": "Upload file size cannot exceed {0} MB!",
"NotAllowedFileExtensionName": "Not allowed file extension: {0}!",
"DisplayName:VersionFileLimitLength": "File limit size",
"Description:VersionFileLimitLength": "Limit size of uploaded file in MB",
"DisplayName:AllowVersionFileExtensions": "File extension",
"Description:AllowVersionFileExtensions": "List of allowed extensions to upload files, with multiple extensions separated by, don't need a notation"
"Description:AllowVersionFileExtensions": "List of allowed extensions to upload files, with multiple extensions separated by, don't need a notation",
"DisplayName:Menus": "Menus",
"DisplayName:Name": "Name",
"DisplayName:Code": "Code",
"DisplayName:IsPublic": "Is Public",
"DisplayName:DisplayName": "Display Name",
"DisplayName:Description": "Description",
"DisplayName:AllowBeNull": "Allow Be Null",
"DisplayName:DefaultValue": "Default Value",
"DisplayName:ValueType": "Value Type",
"DisplayName:Path": "Path",
"DisplayName:Redirect": "Redirect",
"DisplayName:Meta": "Meta",
"DisplayName:Component": "Component",
"DisplayName:Filter": "Filter",
"DisplayName:PlatformType": "Platform Type",
"DisplayName:SecrchMenu": "Secrch Menu",
"DisplayName:SecrchLayout": "Secrch Layout",
"DisplayName:Layout": "Layout",
"DisplayName:Basic": "Basic",
"DisplayName:DataDictionary": "Data Dictionary",
"Layout:AddNew": "Add New",
"Layout:Edit": "Edit",
"Layout:EditByName": "Edit Layout - {0}",
"Layout:Delete": "Delete Layout",
"Menu:AddNew": "Add New",
"Menu:AddChildren": "Add Children",
"Menu:Edit": "Edit",
"Menu:EditByName": "Edit Menu - {0}",
"Menu:Delete": "Delete Menu",
"Menu:Manage": "Manage Menus",
"Data:AddNew": "Add New",
"Data:AddChildren": "Add Children",
"Data:Edit": "Edit",
"Data:Delete": "Delete Data",
"Data:AppendItem": "Append Item",
"Data:EditItem": "Edit Item",
"Data:RemoveItem": "Remove Item",
"Data:Items": "Data Items"
}
}

47
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Localization/Resources/zh-Hans.json

@ -1,12 +1,55 @@
{
"culture": "zh-Hans",
"texts": {
"Platform.VersionFile:404": "文件: {FileName}, 版本号:{FileVersion} 不存在!",
"Platform:01404": "文件: {FileName}, 版本号: {FileVersion} 不存在!",
"Platform:02001": "同级目录下存在相同的菜单: {Name}!",
"Platform:02002": "在有其他子菜单的情况下,不允许删除菜单节点!",
"Platform:02003": "菜单层级已达到规定最大值: {Depth}!",
"Platform:02101": "菜单元数据缺少必要的元素: {Name},此选项在数据字典:{DataName} 中定义!",
"Platform:03001": "元数据格式不匹配!",
"UploadFileSizeBeyondLimit": "上传文件大小不能超过 {0} MB!",
"NotAllowedFileExtensionName": "不被允许的文件扩展名: {0}!",
"DisplayName:VersionFileLimitLength": "文件限制大小",
"Description:VersionFileLimitLength": "上传文件的限制大小,单位(MB)",
"DisplayName:AllowVersionFileExtensions": "文件扩展名",
"Description:AllowVersionFileExtensions": "允许的上传文件扩展名列表,多个扩展名以,分隔,无需输入.符号"
"Description:AllowVersionFileExtensions": "允许的上传文件扩展名列表,多个扩展名以,分隔,无需输入.符号",
"DisplayName:Menus": "菜单列表",
"DisplayName:Name": "名称",
"DisplayName:Code": "编号",
"DisplayName:IsPublic": "是否公用的",
"DisplayName:DisplayName": "显示名称",
"DisplayName:Description": "说明",
"DisplayName:AllowBeNull": "允许空值",
"DisplayName:DefaultValue": "默认值",
"DisplayName:ValueType": "值类型",
"DisplayName:Path": "路径",
"DisplayName:Redirect": "重定向路径",
"DisplayName:Meta": "元数据",
"DisplayName:Component": "组件",
"DisplayName:Filter": "筛选",
"DisplayName:PlatformType": "平台类型",
"DisplayName:SecrchMenu": "查询菜单",
"DisplayName:SecrchLayout": "查询布局",
"DisplayName:Layout": "布局",
"DisplayName:Basic": "基础信息",
"DisplayName:DataDictionary": "数据字典",
"Layout:AddNew": "添加新布局",
"Layout:Edit": "编辑布局",
"Layout:EditByName": "编辑布局 - {0}",
"Layout:Delete": "删除布局",
"Menu:AddNew": "添加新菜单",
"Menu:AddChildren": "添加子菜单",
"Menu:Edit": "编辑菜单",
"Menu:EditByName": "编辑菜单 - {0}",
"Menu:Delete": "删除菜单",
"Menu:Manage": "管理菜单",
"Data:AddNew": "添加新字典",
"Data:AddChildren": "添加下级字典",
"Data:Edit": "编辑字典",
"Data:Delete": "删除字典",
"Data:AppendItem": "添加项目",
"Data:EditItem": "编辑项目",
"Data:RemoveItem": "删除项目",
"Data:Items": "字典项目"
}
}

21
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Menus/MenuConsts.cs

@ -0,0 +1,21 @@
namespace LINGYUN.Platform.Menus
{
public static class MenuConsts
{
public static int MaxComponentLength
{
get;
set;
} = 255;
/// <summary>
/// 最大深度
/// </summary>
/// <remarks>
/// 默认为4,仅支持四级子菜单
/// </remarks>
public const int MaxDepth = 4;
public const int MaxCodeLength = MaxDepth * (PlatformConsts.CodeUnitLength + 1) - 1;
}
}

14
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/PlatformConsts.cs

@ -0,0 +1,14 @@
namespace LINGYUN.Platform
{
public static class PlatformConsts
{
/// <summary>
/// 编号不足位补足字符,如编号为 3,长度5位,补足字符为 0,则编号为00003
/// </summary>
public static char CodePrefix { get; set; } = '0';
/// <summary>
/// 编号长度
/// </summary>
public const int CodeUnitLength = 5;
}
}

6
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/AppPlatformDomainSharedModule.cs → aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/PlatformDomainSharedModule.cs

@ -8,13 +8,13 @@ using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Platform
{
[DependsOn(typeof(AbpLocalizationModule))]
public class AppPlatformDomainSharedModule : AbpModule
public class PlatformDomainSharedModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AppPlatformDomainSharedModule>();
options.FileSets.AddEmbedded<PlatformDomainSharedModule>();
});
Configure<AbpLocalizationOptions>(options =>
@ -27,7 +27,7 @@ namespace LINGYUN.Platform
Configure<AbpExceptionLocalizationOptions>(options =>
{
options.MapCodeNamespace("Platform.VersionFile", typeof(PlatformResource));
options.MapCodeNamespace("Platform", typeof(PlatformResource));
});
}
}

24
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/PlatformErrorCodes.cs

@ -2,6 +2,28 @@
{
public static class PlatformErrorCodes
{
public const string VersionFileNotFound = "Platform.VersionFile:404";
private const string Namespace = "Platform";
public const string VersionFileNotFound = Namespace + ":01404";
/// <summary>
/// 同级菜单已经存在
/// </summary>
public const string DuplicateMenu = Namespace + ":02001";
/// <summary>
/// 不能删除拥有子菜单的节点
/// </summary>
public const string DeleteMenuHaveChildren = Namespace + ":02002";
/// <summary>
/// 菜单层级已达到最大值
/// </summary>
public const string MenuAchieveMaxDepth = Namespace + ":02003";
/// <summary>
/// 菜单元数据缺少必要的元素
/// </summary>
public const string MenuMissingMetadata = Namespace + ":02101";
/// <summary>
/// 元数据格式不匹配
/// </summary>
public const string MetaFormatMissMatch = Namespace + ":03001";
}
}

6
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/PlatformType.cs

@ -53,8 +53,12 @@ namespace LINGYUN.Platform
/// </summary>
Mobile = Android | iOS,
/// <summary>
/// 小程序
/// </summary>
MiniProgram = 256,
/// <summary>
/// 所有平台通用
/// </summary>
All = Desktop | Web | Mobile
All = Desktop | Web | Mobile | MiniProgram
}
}

8
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Routes/RouteConsts.cs

@ -32,7 +32,13 @@
set;
} = 128;
public static int MaxLinkUrlLength
public static int MaxPathLength
{
get;
set;
} = 255;
public static int MaxRedirectLength
{
get;
set;

7
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Routes/RouteEto.cs

@ -7,11 +7,10 @@ namespace LINGYUN.Platform.Routes
{
public Guid? TenantId { get; set; }
public Guid Id { get; set; }
public string Code { get; set; }
public string Path { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
public string LinkUrl { get; set; }
public string Icon { get; set; }
public PlatformType PlatformType { get; set; }
public string Description { get; set; }
public string Redirect { get; set; }
}
}

121
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/Data.cs

@ -0,0 +1,121 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Platform.Datas
{
/// <summary>
/// 数据字典
/// </summary>
public class Data : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual string Name { get; set; }
public virtual string Code { get; set; }
public virtual string DisplayName { get; set; }
public virtual string Description { get; set; }
public virtual Guid? ParentId { get; set; }
public virtual ICollection<DataItem> Items { get; protected set; }
protected Data()
{
Items = new Collection<DataItem>();
}
public Data(
[NotNull] Guid id,
[NotNull] string name,
[NotNull] string code,
[NotNull] string displayName,
string description = "",
Guid? parentId = null,
Guid? tenantId = null)
{
Check.NotNull(id, nameof(id));
Check.NotNullOrWhiteSpace(name, nameof(name));
Check.NotNullOrWhiteSpace(code, nameof(code));
Check.NotNullOrWhiteSpace(displayName, nameof(displayName));
Id = id;
Name = name;
Code = code;
DisplayName = displayName;
Description = description;
ParentId = parentId;
TenantId = tenantId;
CreationTime = DateTime.Now;
Items = new Collection<DataItem>();
}
public Data AddItem(
[NotNull] IGuidGenerator guidGenerator,
[NotNull] string name,
[NotNull] string displayName,
[CanBeNull] string defaultValue,
ValueType valueType = ValueType.String,
string description = "",
bool allowBeNull = true)
{
Check.NotNull(guidGenerator, nameof(guidGenerator));
Check.NotNull(name, nameof(name));
Check.NotNull(displayName, nameof(displayName));
if (!IsInItem(name))
{
var dataItem = new DataItem(
guidGenerator.Create(),
Id,
name,
displayName,
defaultValue,
valueType,
description,
allowBeNull,
TenantId
);
Items.Add(dataItem);
}
return this;
}
public DataItem FindItem(string name)
{
return Items.FirstOrDefault(item => item.Name == name);
}
public DataItem FindItem(Guid id)
{
return Items.FirstOrDefault(item => item.Id == id);
}
public bool RemoveItem(string name)
{
if (IsInItem(name))
{
Items.RemoveAll(item => item.Name == name);
return true;
}
return false;
}
public bool IsInItem(string name)
{
return Items.Any(item => item.Name == name);
}
}
}

50
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/DataDictionaryDataSeeder.cs

@ -0,0 +1,50 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
namespace LINGYUN.Platform.Datas
{
public class DataDictionaryDataSeeder : IDataDictionaryDataSeeder, ITransientDependency
{
protected IGuidGenerator GuidGenerator { get; }
protected IDataRepository DataRepository { get; }
public DataDictionaryDataSeeder(
IGuidGenerator guidGenerator,
IDataRepository dataRepository)
{
GuidGenerator = guidGenerator;
DataRepository = dataRepository;
}
public virtual async Task<Data> SeedAsync(
string name,
string code,
string displayName,
string description = "",
Guid? parentId = null,
Guid? tenantId = null,
CancellationToken cancellationToken = default)
{
var data = await DataRepository.FindByNameAsync(name, cancellationToken: cancellationToken);
if (data == null)
{
data = new Data(
GuidGenerator.Create(),
name,
code,
displayName,
description,
parentId,
tenantId);
data = await DataRepository.InsertAsync(data);
}
return data;
}
}
}

90
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/DataItem.cs

@ -0,0 +1,90 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Platform.Datas
{
public class DataItem : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual string Name { get; protected set; }
public virtual string DisplayName { get; set; }
public virtual string DefaultValue { get; set; }
public virtual string Description { get; set; }
public virtual bool AllowBeNull { get; set; }
public virtual ValueType ValueType { get; protected set; }
public virtual Guid DataId { get; protected set; }
protected DataItem() { }
public DataItem(
[NotNull] Guid id,
[NotNull] Guid dataId,
[NotNull] string name,
[NotNull] string displayName,
[CanBeNull] string defaultValue = null,
ValueType valueType = ValueType.String,
string description = "",
bool allowBeNull = true,
Guid? tenantId = null)
{
Check.NotNull(id, nameof(id));
Check.NotNull(dataId, nameof(dataId));
Check.NotNullOrWhiteSpace(name, nameof(name));
Check.NotNullOrWhiteSpace(displayName, nameof(displayName));
Id = id;
Name = name;
DefaultValue = defaultValue ?? SetDefaultValue();
ValueType = valueType;
DisplayName = displayName;
AllowBeNull = allowBeNull;
DataId = dataId;
TenantId = tenantId;
Description = description;
}
public string SetDefaultValue()
{
switch (ValueType)
{
case ValueType.Array:
DefaultValue = "";// 当数据类型为数组对象时,需要前端来做转换了,约定的分隔符为英文逗号
break;
case ValueType.Boolean:
DefaultValue = "false";
break;
case ValueType.Date:
DefaultValue = !AllowBeNull ? DateTime.Now.ToString("yyyy-MM-dd") : "";
break;
case ValueType.DateTime:
if (!AllowBeNull)
{
DefaultValue = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); // TODO: 以当前时间作为默认值?
}
DefaultValue = !AllowBeNull ? DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") : "";
break;
case ValueType.Numeic:
DefaultValue = "0";
break;
default:
case ValueType.String:
DefaultValue = "";
break;
}
return DefaultValue;
}
}
}

105
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/DataItemMappingOptions.cs

@ -0,0 +1,105 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using Volo.Abp;
namespace LINGYUN.Platform.Datas
{
public class DataItemMappingOptions
{
public Dictionary<ValueType, Func<object, string>> DataItemMaps { get; }
public DataItemMappingOptions()
{
DataItemMaps = new Dictionary<ValueType, Func<object, string>>();
}
internal void SetDefaultMapping()
{
SetMapping(ValueType.Array, value =>
{
if (value == null)
{
return "";
}
if (value is JArray array)
{
var joinString = string.Empty;
foreach (var obj in array.Children())
{
joinString += obj.ToString() + ",";
}
return joinString.EndsWith(",") ? joinString.Substring(0, joinString.Length - 1) : joinString;
}
throw new BusinessException(PlatformErrorCodes.MetaFormatMissMatch);
});
SetMapping(ValueType.Boolean, value =>
{
if (value != null)
{
if (value is bool bo)
{
return bo.ToString().ToLower();
}
else
{
var boInput = value.ToString().ToLower();
if (boInput == "true" ||
boInput == "false")
{
return boInput;
}
}
}
throw new BusinessException(PlatformErrorCodes.MetaFormatMissMatch);
});
SetMapping(ValueType.Date, value =>
{
if (value != null && value is DateTime date)
{
return date.ToString("yyyy-MM-dd");
}
throw new BusinessException(PlatformErrorCodes.MetaFormatMissMatch);
});
SetMapping(ValueType.DateTime, value =>
{
if (value != null && value is DateTime date)
{
return date.ToString("yyyy-MM-dd HH:mm:ss");
}
throw new BusinessException(PlatformErrorCodes.MetaFormatMissMatch);
});
SetMapping(ValueType.Numeic, value =>
{
if (value != null)
{
var valueType = value.GetType();
if (!valueType.IsClass && !valueType.IsInterface && typeof(IFormattable).IsAssignableFrom(valueType))
{
return value.ToString();
}
}
throw new BusinessException(PlatformErrorCodes.MetaFormatMissMatch);
});
SetMapping(ValueType.String, value =>
{
if (value == null)
{
return "";
}
return value.ToString();
});
}
public void SetMapping(ValueType valueType, Func<object, string> func)
{
DataItemMaps[valueType] = func;
}
public string MapToString(ValueType valueType, object inputValue)
{
return DataItemMaps[valueType](inputValue);
}
}
}

18
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/IDataDictionaryDataSeeder.cs

@ -0,0 +1,18 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Platform.Datas
{
public interface IDataDictionaryDataSeeder
{
Task<Data> SeedAsync(
string name,
string code,
string displayName,
string description = "",
Guid? parentId = null,
Guid? tenantId = null,
CancellationToken cancellationToken = default);
}
}

34
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Datas/IDataRepository.cs

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace LINGYUN.Platform.Datas
{
public interface IDataRepository : IBasicRepository<Data, Guid>
{
Task<Data> FindByNameAsync(
string name,
bool includeDetails = true,
CancellationToken cancellationToken = default);
Task<List<Data>> GetChildrenAsync(
Guid? parentId,
bool includeDetails = false,
CancellationToken cancellationToken = default
);
Task<int> GetCountAsync(
string filter = "",
CancellationToken cancellationToken = default);
Task<List<Data>> GetPagedListAsync(
string filter = "",
string sotring = nameof(Data.Code),
bool includeDetails = false,
int skipCount = 0,
int maxResultCount = 10,
CancellationToken cancellationToken = default);
}
}

38
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Layouts/ILayoutRepository.cs

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace LINGYUN.Platform.Layouts
{
public interface ILayoutRepository : IBasicRepository<Layout, Guid>
{
/// <summary>
/// 根据名称查询布局
/// </summary>
/// <param name="name"></param>
/// <param name="includeDetails"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<Layout> FindByNameAsync(
string name,
bool includeDetails = true,
CancellationToken cancellationToken = default);
Task<int> GetCountAsync(
PlatformType? platformType = null,
string filter = "",
CancellationToken cancellationToken = default);
Task<List<Layout>> GetPagedListAsync(
PlatformType? platformType = null,
string filter = "",
string sorting = nameof(Layout.Name),
bool reverse = false,
bool includeDetails = false,
int skipCount = 0,
int maxResultCount = 10,
CancellationToken cancellationToken = default);
}
}

39
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Layouts/Layout.cs

@ -0,0 +1,39 @@
using JetBrains.Annotations;
using LINGYUN.Platform.Routes;
using System;
namespace LINGYUN.Platform.Layouts
{
/// <summary>
/// 布局视图实体
/// </summary>
public class Layout : Route
{
/// <summary>
/// 所属平台
/// </summary>
public virtual PlatformType PlatformType { get; protected set; }
/// <summary>
/// 约定的Meta采用哪种数据字典,主要是约束路由必须字段的一致性
/// </summary>
public virtual Guid DataId { get; protected set; }
protected Layout() { }
public Layout(
[NotNull] Guid id,
[NotNull] string path,
[NotNull] string name,
[NotNull] string displayName,
[NotNull] Guid dataId,
[NotNull] PlatformType platformType = PlatformType.None,
[CanBeNull] string redirect = "",
[CanBeNull] string description = "",
[CanBeNull] Guid? tenantId = null)
: base(id, path, name, displayName, redirect, description, tenantId)
{
DataId = dataId;
PlatformType = platformType;
}
}
}

113
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/IMenuRepository.cs

@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace LINGYUN.Platform.Menus
{
public interface IMenuRepository : IBasicRepository<Menu, Guid>
{
/// <summary>
/// 根据名称查询菜单
/// </summary>
/// <param name="menuName"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<Menu> FindByNameAsync(
string menuName,
CancellationToken cancellationToken = default);
/// <summary>
/// 查询主菜单,每一个布局页创建的时候都要创建路径为 / 的主菜单
/// </summary>
/// <param name="platformType"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<Menu> FindMainAsync(
PlatformType platformType = PlatformType.None,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取子节点
/// </summary>
/// <param name="parentId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<List<Menu>> GetChildrenAsync(
Guid? parentId,
CancellationToken cancellationToken = default
);
/// <summary>
/// 通过父菜单编码查询子菜单
/// </summary>
/// <param name="code"></param>
/// <param name="parentId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<List<Menu>> GetAllChildrenWithParentCodeAsync(
string code,
Guid? parentId,
CancellationToken cancellationToken = default
);
/// <summary>
/// 查找用户可访问菜单
/// </summary>
/// <param name="userId">用户标识</param>
/// <param name="roles">角色列表</param>
/// <param name="platformType">平台类型</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<List<Menu>> GetUserMenusAsync(
Guid userId,
string[] roles,
PlatformType platformType = PlatformType.None,
CancellationToken cancellationToken = default);
/// <summary>
/// 查找角色可访问菜单
/// </summary>
/// <param name="roles">角色列表</param>
/// <param name="platformType">平台类型</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<List<Menu>> GetRoleMenusAsync(
string[] roles,
PlatformType platformType = PlatformType.None,
CancellationToken cancellationToken = default);
Task<int> GetCountAsync(
string filter = "",
PlatformType? platformType = null,
Guid? parentId = null,
Guid? layoutId = null,
CancellationToken cancellationToken = default);
Task<List<Menu>> GetListAsync(
string filter = "",
string sorting = nameof(Menu.Code),
bool reverse = false,
PlatformType? platformType = null,
Guid? parentId = null,
Guid? layoutId = null,
int skipCount = 0,
int maxResultCount = 10,
CancellationToken cancellationToken = default);
Task<List<Menu>> GetAllAsync(
string filter = "",
string sorting = nameof(Menu.Code),
bool reverse = false,
PlatformType? platformType = null,
Guid? parentId = null,
Guid? layoutId = null,
CancellationToken cancellationToken = default);
Task RemoveAllRolesAsync(
Menu menu,
CancellationToken cancellationToken = default
);
Task RemoveAllMembersAsync(
Menu menu,
CancellationToken cancellationToken = default
);
}
}

28
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/IRoleMenuRepository.cs

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace LINGYUN.Platform.Menus
{
public interface IRoleMenuRepository : IBasicRepository<RoleMenu, Guid>
{
/// <summary>
/// 角色是否拥有菜单
/// </summary>
/// <param name="roleName"></param>
/// <param name="menuName"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<bool> RoleHasInMenuAsync(
string roleName,
string menuName,
CancellationToken cancellationToken = default);
Task SetRoleMenusAsync(
string roleName,
IEnumerable<Guid> menuIds,
CancellationToken cancellationToken = default);
}
}

28
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/IUserMenuRepository.cs

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace LINGYUN.Platform.Menus
{
public interface IUserMenuRepository : IBasicRepository<UserMenu, Guid>
{
/// <summary>
/// 用户是否拥有菜单
/// </summary>
/// <param name="userId"></param>
/// <param name="menuName"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<bool> UserHasInMenuAsync(
Guid userId,
string menuName,
CancellationToken cancellationToken = default);
Task SetMemberMenusAsync(
Guid userId,
IEnumerable<Guid> menuIds,
CancellationToken cancellationToken = default);
}
}

67
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/Menu.cs

@ -0,0 +1,67 @@
using JetBrains.Annotations;
using LINGYUN.Platform.Routes;
using System;
using Volo.Abp;
namespace LINGYUN.Platform.Menus
{
/// <summary>
/// 菜单
/// </summary>
public class Menu : Route
{
/// <summary>
/// 所属平台
/// </summary>
public virtual PlatformType PlatformType { get; set; }
/// <summary>
/// 菜单编号
/// </summary>
public virtual string Code { get; set; }
/// <summary>
/// 菜单布局页,Layout的路径
/// </summary>
public virtual string Component { get; set; }
/// <summary>
/// 所属的父菜单
/// </summary>
public virtual Guid? ParentId { get; set; }
/// <summary>
/// 所属布局标识
/// </summary>
public virtual Guid LayoutId { get; set; }
/// <summary>
/// 公共菜单
/// </summary>
public virtual bool IsPublic { get; set; }
protected Menu()
{
}
public Menu(
[NotNull] Guid id,
[NotNull] Guid layoutId,
[NotNull] string path,
[NotNull] string name,
[NotNull] string code,
[NotNull] string component,
[NotNull] string displayName,
string redirect = "",
string description = "",
PlatformType platformType = PlatformType.None,
Guid? parentId = null,
Guid? tenantId = null)
: base(id, path, name, displayName, redirect, description, tenantId)
{
Check.NotNullOrWhiteSpace(code, nameof(code));
LayoutId = layoutId;
Code = code;
Component = component;// 下属的一级菜单的Component应该是布局页, 例如vue-admin中的 component: Layout, 其他前端框架雷同, 此处应传递布局页的路径让前端import
PlatformType = platformType;
ParentId = parentId;
IsPublic = false;
}
}
}

191
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/MenuManager.cs

@ -0,0 +1,191 @@
using LINGYUN.Platform.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Services;
using Volo.Abp.Uow;
namespace LINGYUN.Platform.Menus
{
public class MenuManager : DomainService
{
protected IMenuRepository MenuRepository { get; }
protected IUserMenuRepository UserMenuRepository { get; }
protected IRoleMenuRepository RoleMenuRepository { get; }
public MenuManager(
IMenuRepository menuRepository,
IUserMenuRepository userMenuRepository,
IRoleMenuRepository roleMenuRepository)
{
MenuRepository = menuRepository;
UserMenuRepository = userMenuRepository;
RoleMenuRepository = roleMenuRepository;
}
[UnitOfWork]
public virtual async Task<Menu> CreateAsync(
Guid id,
Guid layoutId,
string path,
string name,
string component,
string displayName,
string redirect = "",
string description = "",
PlatformType platformType = PlatformType.None,
Guid? parentId = null,
Guid? tenantId = null,
bool isPublic = false)
{
var code = await GetNextChildCodeAsync(parentId);
if (code.Length > MenuConsts.MaxCodeLength)
{
throw new BusinessException(PlatformErrorCodes.MenuAchieveMaxDepth)
.WithData("Depth", MenuConsts.MaxDepth);
}
var menu = new Menu(
id,
layoutId,
path,
name,
code,
component,
displayName,
redirect,
description,
platformType,
parentId,
tenantId)
{
IsPublic = isPublic
};
await ValidateMenuAsync(menu);
await MenuRepository.InsertAsync(menu);
return menu;
}
public virtual async Task UpdateAsync(Menu menu)
{
await ValidateMenuAsync(menu);
await MenuRepository.UpdateAsync(menu);
}
[UnitOfWork]
public virtual async Task DeleteAsync(Guid id)
{
var children = await FindChildrenAsync(id, true);
foreach (var child in children)
{
await MenuRepository.RemoveAllMembersAsync(child);
await MenuRepository.RemoveAllRolesAsync(child);
await MenuRepository.DeleteAsync(child);
}
var menu = await MenuRepository.GetAsync(id);
await MenuRepository.RemoveAllMembersAsync(menu);
await MenuRepository.RemoveAllRolesAsync(menu);
await MenuRepository.DeleteAsync(id);
}
[UnitOfWork]
public virtual async Task MoveAsync(Guid id, Guid? parentId)
{
var menu = await MenuRepository.GetAsync(id);
if (menu.ParentId == parentId)
{
return;
}
var children = await FindChildrenAsync(id, true);
var oldCode = menu.Code;
menu.Code = await GetNextChildCodeAsync(parentId);
menu.ParentId = parentId;
await ValidateMenuAsync(menu);
foreach (var child in children)
{
child.Code = CodeNumberGenerator.AppendCode(menu.Code, CodeNumberGenerator.GetRelativeCode(child.Code, oldCode));
}
}
public virtual async Task SetUserMenusAsync(Guid userId, IEnumerable<Guid> menuIds)
{
await UserMenuRepository.SetMemberMenusAsync(userId, menuIds);
}
[UnitOfWork]
public virtual async Task SetRoleMenusAsync(string roleName, IEnumerable<Guid> menuIds)
{
await RoleMenuRepository.SetRoleMenusAsync(roleName, menuIds);
}
protected virtual async Task ValidateMenuAsync(Menu menu)
{
var siblings = (await FindChildrenAsync(menu.ParentId))
.Where(x => x.Id != menu.Id)
.ToList();
if (siblings.Any(ou => ou.Name == menu.Name))
{
throw new BusinessException(PlatformErrorCodes.DuplicateMenu)
.WithData("Name", menu.Name);
}
}
public virtual async Task<string> GetNextChildCodeAsync(Guid? parentId)
{
var lastChild = await GetLastChildOrNullAsync(parentId);
if (lastChild != null)
{
return CodeNumberGenerator.CalculateNextCode(lastChild.Code);
}
var parentCode = parentId != null
? await GetCodeOrDefaultAsync(parentId.Value)
: null;
return CodeNumberGenerator.AppendCode(
parentCode,
CodeNumberGenerator.CreateCode(1)
);
}
public virtual async Task<Menu> GetLastChildOrNullAsync(Guid? parentId)
{
var children = await MenuRepository.GetChildrenAsync(parentId);
return children.OrderBy(c => c.Code).LastOrDefault();
}
public async Task<List<Menu>> FindChildrenAsync(Guid? parentId, bool recursive = false)
{
if (!recursive)
{
return await MenuRepository.GetChildrenAsync(parentId);
}
if (!parentId.HasValue)
{
return await MenuRepository.GetListAsync(includeDetails: true);
}
var code = await GetCodeOrDefaultAsync(parentId.Value);
return await MenuRepository.GetAllChildrenWithParentCodeAsync(code, parentId);
}
public virtual async Task<string> GetCodeOrDefaultAsync(Guid id)
{
var menu = await MenuRepository.GetAsync(id);
return menu?.Code;
}
}
}

35
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/RoleMenu.cs

@ -0,0 +1,35 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Platform.Menus
{
/// <summary>
/// 角色菜单
/// </summary>
public class RoleMenu : AuditedEntity<Guid>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid MenuId { get; protected set; }
public virtual string RoleName { get; protected set; }
protected RoleMenu() { }
public RoleMenu(
Guid menuId,
string roleName,
Guid? tenantId = null)
{
MenuId = menuId;
RoleName = roleName;
TenantId = tenantId;
}
public override object[] GetKeys()
{
return new object[] { MenuId, RoleName };
}
}
}

35
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/UserMenu.cs

@ -0,0 +1,35 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Platform.Menus
{
/// <summary>
/// 用户菜单
/// </summary>
public class UserMenu : AuditedEntity<Guid>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid MenuId { get; protected set; }
public virtual Guid UserId { get; protected set; }
protected UserMenu() { }
public UserMenu(
Guid menuId,
Guid userId,
Guid? tenantId = null)
{
MenuId = menuId;
UserId = userId;
TenantId = tenantId;
}
public override object[] GetKeys()
{
return new object[] { MenuId, UserId };
}
}
}

768
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/PlatformDataSeedContributor.cs

@ -0,0 +1,768 @@
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;
namespace LINGYUN.Platform
{
public class PlatformDataSeedContributor : IDataSeedContributor, ITransientDependency
{
protected IGuidGenerator GuidGenerator { get; }
protected IRouteDataSeeder RouteDataSeeder { get; }
protected IDataDictionaryDataSeeder DataDictionaryDataSeeder { get; }
protected IMenuRepository MenuRepository { get; }
protected ILayoutRepository LayoutRepository { get; }
public PlatformDataSeedContributor(
IRouteDataSeeder routeDataSeeder,
IMenuRepository menuRepository,
ILayoutRepository layoutRepository,
IGuidGenerator guidGenerator,
IDataDictionaryDataSeeder dataDictionaryDataSeeder)
{
GuidGenerator = guidGenerator;
RouteDataSeeder = routeDataSeeder;
MenuRepository = menuRepository;
LayoutRepository = layoutRepository;
DataDictionaryDataSeeder = dataDictionaryDataSeeder;
}
public virtual async Task SeedAsync(DataSeedContext context)
{
var data = await SeedDefaultDataDictionaryAsync(context.TenantId);
// 预置
var layout = await SeedDefaultLayoutAsync(data);
// 首页
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);
}
private async Task<Data> SeedDefaultDataDictionaryAsync(Guid? tenantId)
{
var data = await DataDictionaryDataSeeder
.SeedAsync(
"Layout",
CodeNumberGenerator.CreateCode(1),
"Vue Admin Layout Meta Dictionary",
"Vue Admin Layout Meta Dictionary",
null,
tenantId);
data.AddItem(
GuidGenerator,
"roles", // TODO: 是否需要把这一项写入到预置数据?
"roles",
"",
Datas.ValueType.Array,
"will control the page roles (allow setting multiple roles)");
data.AddItem(
GuidGenerator,
"title",
"title",
"component",
Datas.ValueType.String,
"the name showed in subMenu and breadcrumb (recommend set)");
data.AddItem(
GuidGenerator,
"icon",
"icon",
"icon",
Datas.ValueType.String,
"the icon showed in the sidebar");
data.AddItem(
GuidGenerator,
"hidden",
"hidden",
"false",
Datas.ValueType.Boolean,
"if true, this route will not show in the sidebar (default is false)");
data.AddItem(
GuidGenerator,
"alwaysShow",
"alwaysShow",
"false",
Datas.ValueType.Boolean,
"if true, will always show the root menu (default is false)");
data.AddItem(
GuidGenerator,
"breadcrumb",
"breadcrumb",
"true",
Datas.ValueType.Boolean,
"if false, the item will be hidden in breadcrumb (default is true)");
data.AddItem(
GuidGenerator,
"noCache",
"noCache",
"false",
Datas.ValueType.Boolean,
"if true, the page will not be cached (default is false)");
data.AddItem(
GuidGenerator,
"affix",
"affix",
"false",
Datas.ValueType.Boolean,
"if true, the tag will affix in the tags-view");
data.AddItem(
GuidGenerator,
"activeMenu",
"activeMenu",
"",
Datas.ValueType.String,
"if set path, the sidebar will highlight the path you set");
return data;
}
private async Task<Layout> SeedDefaultLayoutAsync(Data data)
{
var layout = await RouteDataSeeder.SeedLayoutAsync(
"Layout",
"layout/index.vue",
"Vue Admin Layout",
data.Id,
PlatformType.WebMvvm, // 针对当前的vue管理页
"",
"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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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 Organization Units",
"",
"Manage Organization Units",
adminMenu.Id,
layout.TenantId,
new Dictionary<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "title", "identity-server" },
{ "icon", "identity-server" },
{ "alwaysShow", true },
{ "roles", new string[]{ "AbpIdentityServer.Clients", "AbpIdentityServer.ApiResources", "AbpIdentityServer.IdentityResources" } }
},
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<string, object>()
{
{ "title", "clients" },
{ "icon", "clients" },
{ "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<string, object>()
{
{ "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(2)),
"views/admin/identityServer/identity-resources/index.vue",
"Manage Identity Resources",
"",
"Manage Identity Resources",
identityServerMenu.Id,
layout.TenantId,
new Dictionary<string, object>()
{
{ "title", "identity-resources" },
{ "icon", "identity" },
{ "roles", new string[]{ "AbpIdentityServer.IdentityResources" } }
},
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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "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<string, object>()
{
{ "title", "group" },
{ "icon", "group" },
{ "roles", new string[] { "ApiGateway.RouteGroup" } }
},
new string[] { "admin" });
await SeedMenuAsync(
layout,
data,
"global",
"global",
CodeNumberGenerator.AppendCode(apiGatewayMenu.Code, CodeNumberGenerator.CreateCode(1)),
"views/admin/apigateway/global.vue",
"Manage Globals",
"",
"Manage Globals",
apiGatewayMenu.Id,
apiGatewayMenu.TenantId,
new Dictionary<string, object>()
{
{ "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(1)),
"views/admin/apigateway/route.vue",
"Manage Routes",
"",
"Manage Routes",
apiGatewayMenu.Id,
apiGatewayMenu.TenantId,
new Dictionary<string, object>()
{
{ "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(1)),
"views/admin/apigateway/aggregateRoute.vue",
"Manage Aggregate Routes",
"",
"Manage Aggregate Routes",
apiGatewayMenu.Id,
apiGatewayMenu.TenantId,
new Dictionary<string, object>()
{
{ "title", "aggregate-route" },
{ "icon", "aggregate" },
{ "roles", new string[] { "ApiGateway.AggregateRoute " } }
},
new string[] { "admin" });
}
private async Task<Menu> 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<string, object> 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;
}
}
}

2
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/AppPlatformDbProperties.cs → aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/PlatformDbProperties.cs

@ -1,6 +1,6 @@
namespace LINGYUN.Platform
{
public static class AppPlatformDbProperties
public static class PlatformDbProperties
{
public static string DbTablePrefix { get; set; } = "AppPlatform";

6
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/AppPlatformDomainMappingProfile.cs → aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/PlatformDomainMappingProfile.cs

@ -4,13 +4,11 @@ using LINGYUN.Platform.Versions;
namespace LINGYUN.Platform
{
public class AppPlatformDomainMappingProfile : Profile
public class PlatformDomainMappingProfile : Profile
{
public AppPlatformDomainMappingProfile()
public PlatformDomainMappingProfile()
{
CreateMap<Route, RouteEto>();
CreateMap<UserRoute, UserRouteEto>();
CreateMap<RoleRoute, RoleRouteEto>();
CreateMap<AppVersion, AppVersionEto>()
.ForMember(eto => eto.FileCount, map => map.MapFrom(src => src.Files.Count));

22
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/AppPlatformDomainModule.cs → aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/PlatformDomainModule.cs

@ -1,4 +1,5 @@
using LINGYUN.Platform.ObjectExtending;
using LINGYUN.Platform.Datas;
using LINGYUN.Platform.ObjectExtending;
using LINGYUN.Platform.Routes;
using LINGYUN.Platform.Versions;
using Microsoft.Extensions.DependencyInjection;
@ -12,18 +13,23 @@ using Volo.Abp.ObjectExtending.Modularity;
namespace LINGYUN.Platform
{
[DependsOn(
typeof(AppPlatformDomainSharedModule),
typeof(PlatformDomainSharedModule),
typeof(AbpBlobStoringModule),
typeof(AbpEventBusModule))]
public class AppPlatformDomainModule : AbpModule
public class PlatformDomainModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<AppPlatformDomainModule>();
context.Services.AddAutoMapperObjectMapper<PlatformDomainModule>();
Configure<DataItemMappingOptions>(options =>
{
options.SetDefaultMapping();
});
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<AppPlatformDomainMappingProfile>(validate: true);
options.AddProfile<PlatformDomainMappingProfile>(validate: true);
});
Configure<AbpBlobStoringOptions>(options =>
@ -36,11 +42,9 @@ namespace LINGYUN.Platform
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.EtoMappings.Add<Route, RouteEto>(typeof(AppPlatformDomainModule));
options.EtoMappings.Add<UserRoute, UserRouteEto>(typeof(AppPlatformDomainModule));
options.EtoMappings.Add<RoleRoute, RoleRouteEto>(typeof(AppPlatformDomainModule));
options.EtoMappings.Add<Route, RouteEto>(typeof(PlatformDomainModule));
options.EtoMappings.Add<AppVersion, AppVersionEto>(typeof(AppPlatformDomainModule));
options.EtoMappings.Add<AppVersion, AppVersionEto>(typeof(PlatformDomainModule));
options.AutoEventSelectors.Add<AppVersion>();
});

50
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/IRouteDataSeeder.cs

@ -0,0 +1,50 @@
using LINGYUN.Platform.Layouts;
using LINGYUN.Platform.Menus;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Platform.Routes
{
public interface IRouteDataSeeder
{
Task<Layout> SeedLayoutAsync(
string name,
string path,
string displayName,
Guid dataId,
PlatformType platformType = PlatformType.None,
string redirect = "",
string description = "",
Guid? tenantId = null,
CancellationToken cancellationToken = default);
Task<Menu> SeedMenuAsync(
Layout layout,
string name,
string path,
string code,
string component,
string displayName,
string redirect = "",
string description = "",
Guid? parentId = null,
Guid? tenantId = null,
bool isPublic = false,
CancellationToken cancellationToken = default);
Task SeedUserMenuAsync(
Guid userId,
Menu menu,
Guid? tenantId = null,
CancellationToken cancellationToken = default
);
Task SeedRoleMenuAsync(
string roleName,
Menu menu,
Guid? tenantId = null,
CancellationToken cancellationToken = default
);
}
}

78
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/IRouteRepository.cs

@ -1,78 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace LINGYUN.Platform.Routes
{
public interface IRouteRepository : IBasicRepository<Route, Guid>
{
Task<List<Route>> GetChildrenAsync(
Guid? parentId,
CancellationToken cancellationToken = default
);
Task<List<Route>> GetAllChildrenWithParentCodeAsync(
string code,
Guid? parentId,
CancellationToken cancellationToken = default
);
Task<Route> GetAsync(
string displayName,
CancellationToken cancellationToken = default
);
Task<List<Route>> GetPagedListAsync(
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default
);
Task<List<Route>> GetRolesRouteAsync(
string roleName,
CancellationToken cancellationToken = default
);
Task<List<Route>> GetUsersRouteAsync(
Guid userId,
CancellationToken cancellationToken = default
);
Task RemoveAllUsersRouteAsync(
Route route,
CancellationToken cancellationToken = default
);
Task RemoveUserRouteAsync(
Guid userId,
Route route,
CancellationToken cancellationToken = default
);
Task RemoveAllRolesRouteAsync(
Route route,
CancellationToken cancellationToken = default
);
Task RemoveRoleRouteAsync(
string roleName,
Route route,
CancellationToken cancellationToken = default
);
Task<bool> IsInRouteAsync(
string roleName,
Route route,
CancellationToken cancellationToken = default
);
Task<bool> IsInRouteAsync(
Guid userId,
Route route,
CancellationToken cancellationToken = default
);
}
}

31
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/RoleRoute.cs

@ -1,31 +0,0 @@
using JetBrains.Annotations;
using System;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Platform.Routes
{
public class RoleRoute : FullAuditedEntity<int>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual string RoleName { get; protected set; }
public virtual Guid RouteId { get; protected set; }
protected RoleRoute()
{
}
public RoleRoute(int id)
{
Id = id;
}
public RoleRoute(Guid routeId, [NotNull] string roleName, Guid? tenantId = null)
{
RouteId = routeId;
TenantId = tenantId;
RoleName = Check.NotNullOrWhiteSpace(roleName, nameof(roleName));
}
}
}

186
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/Route.cs

@ -1,193 +1,79 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Platform.Routes
{
// TODO: 因为abp的菜单设计模式是按照权限分配的,是否可以去掉路由的后台配置?
// 按钮、菜单权限可以在子权限中定义
// 数据权限需要DbContext拦截器或者创建一个数据过滤仓储的抽象类,需要过滤数据权限的继承自此仓储
public class Route : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
/// <summary>
/// 租户标识
/// 不管是布局还是视图或者页面,都作为路由的实现,因此抽象一个路由实体<br/>
/// 注意:这是基于 Vue Router 的路由规则设计的实体,详情:https://router.vuejs.org/zh/api/#routes
/// </summary>
public abstract class Route : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 编号
/// 路径
/// </summary>
public virtual string Code { get; set; }
public virtual string Path { get; set; }
/// <summary>
/// 名称
/// </summary>
public virtual string Name { get; protected set; }
/// <summary>
/// 全名
/// </summary>
public virtual string FullName { get; set; }
public virtual string Name { get; set; }
/// <summary>
/// 显示名称
/// </summary>
public virtual string DisplayName { get; protected set; }
/// <summary>
/// 平台标识
/// </summary>
public virtual PlatformType PlatformType { get; set; }
public virtual string DisplayName { get; set; }
/// <summary>
/// 说明
/// </summary>
public virtual string Description { get; set; }
/// <summary>
/// 图标
/// </summary>
public virtual string Icon { get; protected set; }
/// <summary>
/// 路由地址
/// </summary>
public virtual string LinkUrl { get; protected set; }
/// <summary>
/// 是否菜单
/// </summary>
public virtual bool IsMenu { get; set; }
/// <summary>
/// 是否工具栏
/// </summary>
public virtual bool IsToolBar { get; set; }
/// <summary>
/// 是否侧边栏
/// </summary>
public virtual bool IsSideBar { get; set; }
/// <summary>
/// 是否公共路由
/// </summary>
public virtual bool IsPublic { get; set; }
/// <summary>
/// 是否内置
/// 重定向路径
/// </summary>
public virtual bool IsStatic { get; set; }
/// <summary>
/// 总是显示根菜单
/// </summary>
public virtual bool AlwaysShow { get; set; }
/// <summary>
/// 父级标识
/// </summary>
public virtual Guid? ParentId { get; set; }
protected Route()
{
}
public Route(Guid id, string name, string displayName, string url)
{
Id = id;
LinkToUrl(url);
ChangeName(name, displayName);
}
public virtual string Redirect { get; set; }
public void LinkToUrl([NotNull] string linkUrl)
{
LinkUrl = Check.NotNullOrWhiteSpace(linkUrl, nameof(linkUrl));
}
protected Route() { }
public void ChangeIcon(string icon)
protected Route(
[NotNull] Guid id,
[NotNull] string path,
[NotNull] string name,
[NotNull] string displayName,
[CanBeNull] string redirect = "",
[CanBeNull] string description = "",
[CanBeNull] Guid? tenantId = null)
: base(id)
{
Icon = icon;
}
Check.NotNullOrWhiteSpace(path, nameof(path));
Check.NotNullOrWhiteSpace(name, nameof(name));
Check.NotNullOrWhiteSpace(displayName, nameof(displayName));
public void ChangeName([NotNull] string name, [CanBeNull] string displayName)
{
Name = Check.NotNullOrWhiteSpace(name, nameof(name));
Path = path;
Name = name;
DisplayName = displayName;
Redirect = redirect;
Description = description;
TenantId = tenantId;
}
public static string CreateCode(params int[] numbers)
public override int GetHashCode()
{
if (numbers.IsNullOrEmpty())
{
return null;
}
return numbers.Select(number => number.ToString(new string('0', RouteConsts.CodeUnitLength))).JoinAsString(".");
return Name.GetHashCode();
}
public static string AppendCode(string parentCode, string childCode)
public override bool Equals(object obj)
{
if (childCode.IsNullOrEmpty())
if (obj == null)
{
throw new ArgumentNullException(nameof(childCode), "childCode can not be null or empty.");
return false;
}
if (parentCode.IsNullOrEmpty())
if (obj is Route route)
{
return childCode;
return route.Name.Equals(Name, StringComparison.InvariantCultureIgnoreCase);
}
return parentCode + "." + childCode;
}
public static string GetRelativeCode(string code, string parentCode)
{
if (code.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(code), "code can not be null or empty.");
}
if (parentCode.IsNullOrEmpty())
{
return code;
}
if (code.Length == parentCode.Length)
{
return null;
}
return code.Substring(parentCode.Length + 1);
}
public static string CalculateNextCode(string code)
{
if (code.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(code), "code can not be null or empty.");
}
var parentCode = GetParentCode(code);
var lastUnitCode = GetLastUnitCode(code);
return AppendCode(parentCode, CreateCode(Convert.ToInt32(lastUnitCode) + 1));
}
public static string GetLastUnitCode(string code)
{
if (code.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(code), "code can not be null or empty.");
}
var splittedCode = code.Split('.');
return splittedCode[splittedCode.Length - 1];
}
public static string GetParentCode(string code)
{
if (code.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(code), "code can not be null or empty.");
}
var splittedCode = code.Split('.');
if (splittedCode.Length == 1)
{
return null;
}
return splittedCode.Take(splittedCode.Length - 1).JoinAsString(".");
return base.Equals(obj);
}
}
}

150
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/RouteDataSeeder.cs

@ -0,0 +1,150 @@
using LINGYUN.Platform.Layouts;
using LINGYUN.Platform.Menus;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
namespace LINGYUN.Platform.Routes
{
public class RouteDataSeeder : IRouteDataSeeder, ITransientDependency
{
protected IGuidGenerator GuidGenerator { get; }
protected ILayoutRepository LayoutRepository { get; }
protected IMenuRepository MenuRepository { get; }
protected IUserMenuRepository UserMenuRepository { get; }
protected IRoleMenuRepository RoleMenuRepository { get; }
public RouteDataSeeder(
IGuidGenerator guidGenerator,
IMenuRepository menuRepository,
ILayoutRepository layoutRepository,
IUserMenuRepository userMenuRepository,
IRoleMenuRepository roleMenuRepository)
{
GuidGenerator = guidGenerator;
MenuRepository = menuRepository;
LayoutRepository = layoutRepository;
UserMenuRepository = userMenuRepository;
RoleMenuRepository = roleMenuRepository;
}
public virtual async Task<Layout> SeedLayoutAsync(
string name,
string path,
string displayName,
Guid dataId,
PlatformType platformType = PlatformType.None,
string redirect = "",
string description = "",
Guid? tenantId = null,
CancellationToken cancellationToken = default)
{
var layout = await LayoutRepository.FindByNameAsync(name, cancellationToken: cancellationToken);
if (layout == null)
{
layout = new Layout(
GuidGenerator.Create(),
path,
name,
displayName,
dataId,
platformType,
redirect,
description,
tenantId);
layout = await LayoutRepository.InsertAsync(layout, cancellationToken: cancellationToken);
}
return layout;
}
public virtual async Task<Menu> SeedMenuAsync(
Layout layout,
string name,
string path,
string code,
string component,
string displayName,
string redirect = "",
string description = "",
Guid? parentId = null,
Guid? tenantId = null,
bool isPublic = false,
CancellationToken cancellationToken = default)
{
if (parentId.HasValue)
{
var children = await MenuRepository.GetChildrenAsync(parentId);
var childMenu = children.FirstOrDefault(x => x.Name == name);
if (childMenu != null)
{
return childMenu;
}
}
var menu = await MenuRepository.FindByNameAsync(name, cancellationToken: cancellationToken);
if (menu == null)
{
menu = new Menu(
GuidGenerator.Create(),
layout.Id,
path,
name,
code,
component,
displayName,
redirect,
description,
layout.PlatformType,
parentId,
tenantId)
{
IsPublic = isPublic
};
menu = await MenuRepository.InsertAsync(menu, cancellationToken: cancellationToken);
}
return menu;
}
public virtual async Task SeedRoleMenuAsync(
string roleName,
Menu menu,
Guid? tenantId = null,
CancellationToken cancellationToken = default)
{
if (! await RoleMenuRepository.RoleHasInMenuAsync(roleName, menu.Name, cancellationToken))
{
var roleMenu = new RoleMenu(menu.Id, roleName, tenantId);
await RoleMenuRepository.InsertAsync(roleMenu);
var childrens = await MenuRepository.GetChildrenAsync(menu.Id);
foreach (var children in childrens)
{
await SeedRoleMenuAsync(roleName, children, tenantId, cancellationToken);
}
}
}
public virtual async Task SeedUserMenuAsync(
Guid userId,
Menu menu,
Guid? tenantId = null,
CancellationToken cancellationToken = default)
{
if (!await UserMenuRepository.UserHasInMenuAsync(userId, menu.Name, cancellationToken))
{
var userMenu = new UserMenu(menu.Id, userId, tenantId);
await UserMenuRepository.InsertAsync(userMenu);
var childrens = await MenuRepository.GetChildrenAsync(menu.Id);
foreach (var children in childrens)
{
await SeedUserMenuAsync(userId, children, tenantId, cancellationToken);
}
}
}
}
}

139
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/RouteManager.cs

@ -1,139 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Domain.Services;
using Volo.Abp.Uow;
namespace LINGYUN.Platform.Routes
{
public class RouteManager : DomainService
{
protected IRouteRepository RouteRepository { get; }
public RouteManager(
IRouteRepository routeRepository)
{
RouteRepository = routeRepository;
}
[UnitOfWork]
public virtual async Task CreateAsync(Route route)
{
route.Code = await GetNextChildCodeAsync(route.ParentId);
await RouteRepository.InsertAsync(route);
}
public virtual async Task UpdateAsync(Route route)
{
await RouteRepository.UpdateAsync(route);
}
[UnitOfWork]
public virtual async Task DeleteAsync(Guid id)
{
var children = await FindChildrenAsync(id, true);
foreach (var child in children)
{
await RouteRepository.RemoveAllUsersRouteAsync(child);
await RouteRepository.RemoveAllRolesRouteAsync(child);
await RouteRepository.DeleteAsync(child);
}
var organizationUnit = await RouteRepository.GetAsync(id);
await RouteRepository.RemoveAllUsersRouteAsync(organizationUnit);
await RouteRepository.RemoveAllRolesRouteAsync(organizationUnit);
await RouteRepository.DeleteAsync(id);
}
[UnitOfWork]
public virtual async Task MoveAsync(Guid id, Guid? parentId)
{
var route = await RouteRepository.GetAsync(id);
if (route.ParentId == parentId)
{
return;
}
var children = await FindChildrenAsync(id, true);
var oldCode = route.Code;
route.Code = await GetNextChildCodeAsync(parentId);
route.ParentId = parentId;
foreach (var child in children)
{
child.Code = Route.AppendCode(route.Code, Route.GetRelativeCode(child.Code, oldCode));
}
}
public virtual async Task RemoveRoleFromRouteAsync(string roleName, Route route)
{
await RouteRepository.RemoveRoleRouteAsync(roleName, route);
}
public virtual async Task RemoveUserFromRouteAsync(Guid userId, Route route)
{
await RouteRepository.RemoveUserRouteAsync(userId, route);
}
public virtual async Task<string> GetNextChildCodeAsync(Guid? parentId)
{
var lastChild = await GetLastChildOrNullAsync(parentId);
if (lastChild != null)
{
return Route.CalculateNextCode(lastChild.Code);
}
var parentCode = parentId != null
? await GetCodeOrDefaultAsync(parentId.Value)
: null;
return Route.AppendCode(
parentCode,
Route.CreateCode(1)
);
}
public virtual async Task<Route> GetLastChildOrNullAsync(Guid? parentId)
{
var children = await RouteRepository.GetChildrenAsync(parentId);
return children.OrderBy(c => c.Code).LastOrDefault();
}
public virtual async Task<string> GetCodeOrDefaultAsync(Guid id)
{
var ou = await RouteRepository.GetAsync(id);
return ou?.Code;
}
public async Task<List<Route>> FindChildrenAsync(Guid? parentId, bool recursive = false)
{
if (!recursive)
{
return await RouteRepository.GetChildrenAsync(parentId);
}
if (!parentId.HasValue)
{
return await RouteRepository.GetListAsync();
}
var code = await GetCodeOrDefaultAsync(parentId.Value);
return await RouteRepository.GetAllChildrenWithParentCodeAsync(code, parentId);
}
public virtual async Task<bool> IsInRouteAsync(Guid userId, Route route)
{
return await RouteRepository.IsInRouteAsync(userId, route);
}
public virtual async Task<bool> IsInRouteAsync(string roleName, Route route)
{
return await RouteRepository.IsInRouteAsync(roleName, route);
}
}
}

29
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Routes/UserRoute.cs

@ -1,29 +0,0 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Platform.Routes
{
public class UserRoute : FullAuditedEntity<int>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid UserId { get; protected set; }
public virtual Guid RouteId { get; protected set; }
protected UserRoute()
{
}
public UserRoute(int id)
{
Id = id;
}
public UserRoute(Guid routeId, Guid userId, Guid? tenantId = null)
{
UserId = userId;
RouteId = routeId;
TenantId = tenantId;
}
}
}

94
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Utils/CodeNumberGenerator.cs

@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINGYUN.Platform.Utils
{
public static class CodeNumberGenerator
{
public static string CreateCode(params int[] numbers)
{
if (numbers.IsNullOrEmpty())
{
return null;
}
return numbers.Select(number => number.ToString(new string(PlatformConsts.CodePrefix, PlatformConsts.CodeUnitLength))).JoinAsString(".");
}
public static string AppendCode(string parentCode, string childCode)
{
if (childCode.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(childCode), "childCode can not be null or empty.");
}
if (parentCode.IsNullOrEmpty())
{
return childCode;
}
return parentCode + "." + childCode;
}
public static string GetRelativeCode(string code, string parentCode)
{
if (code.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(code), "code can not be null or empty.");
}
if (parentCode.IsNullOrEmpty())
{
return code;
}
if (code.Length == parentCode.Length)
{
return null;
}
return code.Substring(parentCode.Length + 1);
}
public static string CalculateNextCode(string code)
{
if (code.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(code), "code can not be null or empty.");
}
var parentCode = GetParentCode(code);
var lastUnitCode = GetLastCode(code);
return AppendCode(parentCode, CreateCode(Convert.ToInt32(lastUnitCode) + 1));
}
public static string GetLastCode(string code)
{
if (code.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(code), "code can not be null or empty.");
}
var splittedCode = code.Split('.');
return splittedCode[splittedCode.Length - 1];
}
public static string GetParentCode(string code)
{
if (code.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(code), "code can not be null or empty.");
}
var splittedCode = code.Split('.');
if (splittedCode.Length == 1)
{
return null;
}
return splittedCode.Take(splittedCode.Length - 1).JoinAsString(".");
}
}
}

79
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/Datas/EfCoreDataRepository.cs

@ -0,0 +1,79 @@
using LINGYUN.Platform.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Platform.Datas
{
public class EfCoreDataRepository : EfCoreRepository<PlatformDbContext, Data, Guid>, IDataRepository
{
public EfCoreDataRepository(
IDbContextProvider<PlatformDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public virtual async Task<Data> FindByNameAsync(
string name,
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await DbSet
.IncludeDetails(includeDetails)
.Where(x => x.Name == name)
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<Data>> GetChildrenAsync(
Guid? parentId,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await DbSet
.IncludeDetails(includeDetails)
.Where(x => x.ParentId == parentId)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<int> GetCountAsync(
string filter = "",
CancellationToken cancellationToken = default)
{
return await DbSet
.WhereIf(!filter.IsNullOrWhiteSpace(), x =>
x.Code.Contains(filter) || x.Description.Contains(filter) ||
x.DisplayName.Contains(filter) || x.Name.Contains(filter))
.CountAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<Data>> GetPagedListAsync(
string filter = "",
string sotring = "Code",
bool includeDetails = false,
int skipCount = 0,
int maxResultCount = 10,
CancellationToken cancellationToken = default)
{
sotring ??= nameof(Data.Code);
return await DbSet
.IncludeDetails(includeDetails)
.WhereIf(!filter.IsNullOrWhiteSpace(), x =>
x.Code.Contains(filter) || x.Description.Contains(filter) ||
x.DisplayName.Contains(filter) || x.Name.Contains(filter))
.OrderBy(sotring)
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public override IQueryable<Data> WithDetails()
{
return GetQueryable().IncludeDetails();
}
}
}

143
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/AppPlatformDbContextModelBuilderExtensions.cs

@ -1,143 +0,0 @@
using LINGYUN.Platform.Routes;
using LINGYUN.Platform.Versions;
using Microsoft.EntityFrameworkCore;
using System;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace LINGYUN.Platform.EntityFrameworkCore
{
public static class AppPlatformDbContextModelBuilderExtensions
{
public static void ConfigurePlatform(
this ModelBuilder builder,
Action<AppPlatformModelBuilderConfigurationOptions> optionsAction = null)
{
Check.NotNull(builder, nameof(builder));
var options = new AppPlatformModelBuilderConfigurationOptions(
AppPlatformDbProperties.DbTablePrefix,
AppPlatformDbProperties.DbSchema
);
optionsAction?.Invoke(options);
builder.Entity<Route>(x =>
{
x.ToTable(options.TablePrefix + "Route");
x.Property(p => p.Code)
.IsRequired()
.HasMaxLength(RouteConsts.MaxCodeLength)
.HasColumnName(nameof(Route.Code));
x.Property(p => p.DisplayName)
.IsRequired()
.HasMaxLength(RouteConsts.MaxDisplayNameLength)
.HasColumnName(nameof(Route.DisplayName));
x.Property(p => p.LinkUrl)
.IsRequired()
.HasMaxLength(RouteConsts.MaxLinkUrlLength)
.HasColumnName(nameof(Route.LinkUrl));
x.Property(p => p.Name)
.IsRequired()
.HasMaxLength(RouteConsts.MaxNameLength)
.HasColumnName(nameof(Route.Name));
x.Property(p => p.Icon)
.HasMaxLength(RouteConsts.MaxIconLength)
.HasColumnName(nameof(Route.Icon));
x.Property(p => p.FullName)
.HasMaxLength(RouteConsts.MaxFullNameLength)
.HasColumnName(nameof(Route.FullName));
x.Property(p => p.Description)
.HasMaxLength(RouteConsts.MaxDescriptionLength)
.HasColumnName(nameof(Route.Description));
x.ConfigureByConvention();
x.HasMany<Route>().WithOne().HasForeignKey(p => p.ParentId);
x.HasIndex(i => i.Code);
});
builder.Entity<RoleRoute>(x =>
{
x.ToTable(options.TablePrefix + "RoleRoute");
x.Property(p => p.RoleName)
.IsRequired()
.HasMaxLength(RoleRouteConsts.MaxRoleNameLength)
.HasColumnName(nameof(RoleRoute.RoleName));
x.ConfigureMultiTenant();
x.HasIndex(i => new { i.RoleName, i.RouteId });
});
builder.Entity<UserRoute>(x =>
{
x.ToTable(options.TablePrefix + "UserRoute");
x.ConfigureMultiTenant();
x.HasIndex(i => new { i.UserId, i.RouteId });
});
builder.Entity<AppVersion>(x =>
{
x.ToTable(options.TablePrefix + "Version", options.Schema);
x.Property(p => p.Title)
.IsRequired()
.HasColumnName(nameof(AppVersion.Title))
.HasMaxLength(AppVersionConsts.MaxTitleLength);
x.Property(p => p.Version)
.IsRequired()
.HasColumnName(nameof(AppVersion.Version))
.HasMaxLength(AppVersionConsts.MaxVersionLength);
x.Property(p => p.Description)
.HasColumnName(nameof(AppVersion.Description))
.HasMaxLength(AppVersionConsts.MaxDescriptionLength);
x.ConfigureByConvention();
x.HasIndex(i => i.Version);
x.HasMany(p => p.Files)
.WithOne(q => q.AppVersion)
.HasPrincipalKey(pk => pk.Id)
.HasForeignKey(fk => fk.AppVersionId)
.OnDelete(DeleteBehavior.Cascade);
});
builder.Entity<VersionFile>(x =>
{
x.ToTable(options.TablePrefix + "VersionFile", options.Schema);
x.Property(p => p.Name)
.IsRequired()
.HasColumnName(nameof(VersionFile.Name))
.HasMaxLength(VersionFileConsts.MaxNameLength);
x.Property(p => p.SHA256)
.IsRequired()
.HasColumnName(nameof(VersionFile.SHA256))
.HasMaxLength(VersionFileConsts.MaxSHA256Length);
x.Property(p => p.Version)
.IsRequired()
.HasColumnName(nameof(VersionFile.Version))
.HasMaxLength(VersionFileConsts.MaxVersionLength);
x.Property(p => p.Path)
.HasColumnName(nameof(VersionFile.Path))
.HasMaxLength(VersionFileConsts.MaxPathLength);
x.ConfigureAudited();
x.ConfigureMultiTenant();
x.HasIndex(i => new { i.Path, i.Name, i.Version }).IsUnique();
});
}
}
}

10
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/IPlatformDbContext.cs

@ -1,4 +1,6 @@
using LINGYUN.Platform.Routes;
using LINGYUN.Platform.Datas;
using LINGYUN.Platform.Layouts;
using LINGYUN.Platform.Menus;
using LINGYUN.Platform.Versions;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
@ -6,10 +8,12 @@ using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Platform.EntityFrameworkCore
{
[ConnectionStringName(AppPlatformDbProperties.ConnectionStringName)]
[ConnectionStringName(PlatformDbProperties.ConnectionStringName)]
public interface IPlatformDbContext : IEfCoreDbContext
{
DbSet<Route> Routes { get; set; }
DbSet<Menu> Menus { get; set; }
DbSet<Layout> Layouts { get; set; }
DbSet<Data> Datas { get; set; }
DbSet<AppVersion> AppVersions { get; set; }
}
}

10
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/PlatformDbContext.cs

@ -1,4 +1,6 @@
using LINGYUN.Platform.Routes;
using LINGYUN.Platform.Datas;
using LINGYUN.Platform.Layouts;
using LINGYUN.Platform.Menus;
using LINGYUN.Platform.Versions;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
@ -6,10 +8,12 @@ using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Platform.EntityFrameworkCore
{
[ConnectionStringName(AppPlatformDbProperties.ConnectionStringName)]
[ConnectionStringName(PlatformDbProperties.ConnectionStringName)]
public class PlatformDbContext : AbpDbContext<PlatformDbContext>, IPlatformDbContext
{
public DbSet<Route> Routes { get; set; }
public DbSet<Menu> Menus { get; set; }
public DbSet<Layout> Layouts { get; set; }
public DbSet<Data> Datas { get; set; }
public DbSet<AppVersion> AppVersions { get; set; }

249
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/PlatformDbContextModelBuilderExtensions.cs

@ -0,0 +1,249 @@
using JetBrains.Annotations;
using LINGYUN.Platform.Datas;
using LINGYUN.Platform.Layouts;
using LINGYUN.Platform.Menus;
using LINGYUN.Platform.Routes;
using LINGYUN.Platform.Versions;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace LINGYUN.Platform.EntityFrameworkCore
{
public static class PlatformDbContextModelBuilderExtensions
{
public static void ConfigurePlatform(
this ModelBuilder builder,
Action<PlatformModelBuilderConfigurationOptions> optionsAction = null)
{
Check.NotNull(builder, nameof(builder));
var options = new PlatformModelBuilderConfigurationOptions(
PlatformDbProperties.DbTablePrefix,
PlatformDbProperties.DbSchema
);
optionsAction?.Invoke(options);
builder.Entity<Layout>(b =>
{
b.ToTable(options.TablePrefix + "Layouts", options.Schema);
b.ConfigureRoute();
});
builder.Entity<Menu>(b =>
{
b.ToTable(options.TablePrefix + "Menus", options.Schema);
b.ConfigureRoute();
b.Property(p => p.Component)
.HasMaxLength(MenuConsts.MaxComponentLength)
.HasColumnName(nameof(Menu.Component))
.IsRequired();
b.Property(p => p.Code)
.HasMaxLength(MenuConsts.MaxCodeLength)
.HasColumnName(nameof(Menu.Code))
.IsRequired();
});
builder.Entity<RoleMenu>(x =>
{
x.ToTable(options.TablePrefix + "RoleMenus");
x.Property(p => p.RoleName)
.IsRequired()
.HasMaxLength(RoleRouteConsts.MaxRoleNameLength)
.HasColumnName(nameof(RoleMenu.RoleName));
x.ConfigureByConvention();
x.HasIndex(i => new { i.RoleName, i.MenuId });
});
builder.Entity<UserMenu>(x =>
{
x.ToTable(options.TablePrefix + "UserMenus");
x.ConfigureByConvention();
x.HasIndex(i => new { i.UserId, i.MenuId });
});
builder.Entity<Data>(x =>
{
x.ToTable(options.TablePrefix + "Datas");
x.Property(p => p.Code)
.HasMaxLength(DataConsts.MaxCodeLength)
.HasColumnName(nameof(Data.Code))
.IsRequired();
x.Property(p => p.Name)
.HasMaxLength(DataConsts.MaxNameLength)
.HasColumnName(nameof(Data.Name))
.IsRequired();
x.Property(p => p.DisplayName)
.HasMaxLength(DataConsts.MaxDisplayNameLength)
.HasColumnName(nameof(Data.DisplayName))
.IsRequired();
x.Property(p => p.Description)
.HasMaxLength(DataConsts.MaxDescriptionLength)
.HasColumnName(nameof(Data.Description));
x.ConfigureByConvention();
x.HasMany(p => p.Items)
.WithOne()
.HasForeignKey(fk => fk.DataId)
.IsRequired();
x.HasIndex(i => new { i.Name });
});
builder.Entity<DataItem>(x =>
{
x.ToTable(options.TablePrefix + "DataItems");
x.Property(p => p.DefaultValue)
.HasMaxLength(DataItemConsts.MaxValueLength)
.HasColumnName(nameof(DataItem.DefaultValue));
x.Property(p => p.Name)
.HasMaxLength(DataItemConsts.MaxNameLength)
.HasColumnName(nameof(DataItem.Name))
.IsRequired();
x.Property(p => p.DisplayName)
.HasMaxLength(DataItemConsts.MaxDisplayNameLength)
.HasColumnName(nameof(DataItem.DisplayName))
.IsRequired();
x.Property(p => p.Description)
.HasMaxLength(DataItemConsts.MaxDescriptionLength)
.HasColumnName(nameof(DataItem.Description));
x.Property(p => p.AllowBeNull).HasDefaultValue(true);
x.ConfigureByConvention();
x.HasIndex(i => new { i.Name });
});
builder.Entity<AppVersion>(x =>
{
x.ToTable(options.TablePrefix + "Version", options.Schema);
x.Property(p => p.Title)
.IsRequired()
.HasColumnName(nameof(AppVersion.Title))
.HasMaxLength(AppVersionConsts.MaxTitleLength);
x.Property(p => p.Version)
.IsRequired()
.HasColumnName(nameof(AppVersion.Version))
.HasMaxLength(AppVersionConsts.MaxVersionLength);
x.Property(p => p.Description)
.HasColumnName(nameof(AppVersion.Description))
.HasMaxLength(AppVersionConsts.MaxDescriptionLength);
x.ConfigureByConvention();
x.HasIndex(i => i.Version);
x.HasMany(p => p.Files)
.WithOne(q => q.AppVersion)
.HasPrincipalKey(pk => pk.Id)
.HasForeignKey(fk => fk.AppVersionId)
.OnDelete(DeleteBehavior.Cascade);
});
builder.Entity<VersionFile>(x =>
{
x.ToTable(options.TablePrefix + "VersionFile", options.Schema);
x.Property(p => p.Name)
.IsRequired()
.HasColumnName(nameof(VersionFile.Name))
.HasMaxLength(VersionFileConsts.MaxNameLength);
x.Property(p => p.SHA256)
.IsRequired()
.HasColumnName(nameof(VersionFile.SHA256))
.HasMaxLength(VersionFileConsts.MaxSHA256Length);
x.Property(p => p.Version)
.IsRequired()
.HasColumnName(nameof(VersionFile.Version))
.HasMaxLength(VersionFileConsts.MaxVersionLength);
x.Property(p => p.Path)
.HasColumnName(nameof(VersionFile.Path))
.HasMaxLength(VersionFileConsts.MaxPathLength);
x.ConfigureAudited();
x.ConfigureMultiTenant();
x.HasIndex(i => new { i.Path, i.Name, i.Version }).IsUnique();
});
}
public static EntityTypeBuilder<TRoute> ConfigureRoute<TRoute>(
this EntityTypeBuilder<TRoute> builder)
where TRoute : Route
{
builder
.Property(p => p.DisplayName)
.HasMaxLength(RouteConsts.MaxDisplayNameLength)
.HasColumnName(nameof(Route.DisplayName))
.IsRequired();
builder
.Property(p => p.Name)
.HasMaxLength(RouteConsts.MaxNameLength)
.HasColumnName(nameof(Route.Name))
.IsRequired();
builder
.Property(p => p.Path)
.HasMaxLength(RouteConsts.MaxPathLength)
.HasColumnName(nameof(Route.Path));
builder
.Property(p => p.Redirect)
.HasMaxLength(RouteConsts.MaxRedirectLength)
.HasColumnName(nameof(Route.Redirect));
builder.ConfigureByConvention();
return builder;
}
public static OwnedNavigationBuilder<TEntity, TRoute> ConfigureRoute<TEntity, TRoute>(
[NotNull] this OwnedNavigationBuilder<TEntity, TRoute> builder,
[CanBeNull] string tablePrefix = "",
[CanBeNull] string schema = null)
where TEntity : class
where TRoute : Route
{
builder.ToTable(tablePrefix + "Routes", schema);
builder
.Property(p => p.DisplayName)
.HasMaxLength(RouteConsts.MaxDisplayNameLength)
.HasColumnName(nameof(Route.DisplayName))
.IsRequired();
builder
.Property(p => p.Name)
.HasMaxLength(RouteConsts.MaxNameLength)
.HasColumnName(nameof(Route.Name))
.IsRequired();
builder
.Property(p => p.Path)
.HasMaxLength(RouteConsts.MaxPathLength)
.HasColumnName(nameof(Route.Path));
builder
.Property(p => p.Redirect)
.HasMaxLength(RouteConsts.MaxRedirectLength)
.HasColumnName(nameof(Route.Redirect));
return builder;
}
}
}

34
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/PlatformEfCoreQueryableExtensions.cs

@ -0,0 +1,34 @@
using LINGYUN.Platform.Datas;
using LINGYUN.Platform.Layouts;
using LINGYUN.Platform.Menus;
using Microsoft.EntityFrameworkCore;
using System.Linq;
namespace LINGYUN.Platform.EntityFrameworkCore
{
public static class PlatformEfCoreQueryableExtensions
{
public static IQueryable<Layout> IncludeDetails(this IQueryable<Layout> queryable, bool include = true)
{
if (!include)
{
return queryable;
}
return queryable;
}
public static IQueryable<Data> IncludeDetails(this IQueryable<Data> queryable, bool include = true)
{
if (!include)
{
return queryable;
}
return queryable
//.AsSplitQuery()
.Include(x => x.Items);
}
}
}

14
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/AppPlatformEntityFrameworkCoreModule.cs → aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/PlatformEntityFrameworkCoreModule.cs

@ -1,4 +1,6 @@
using LINGYUN.Platform.Routes;
using LINGYUN.Platform.Datas;
using LINGYUN.Platform.Layouts;
using LINGYUN.Platform.Menus;
using LINGYUN.Platform.Versions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
@ -8,15 +10,19 @@ using Volo.Abp.Modularity;
namespace LINGYUN.Platform.EntityFrameworkCore
{
[DependsOn(
typeof(AppPlatformDomainModule),
typeof(PlatformDomainModule),
typeof(AbpEntityFrameworkCoreModule))]
public class AppPlatformEntityFrameworkCoreModule : AbpModule
public class PlatformEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<PlatformDbContext>(options =>
{
options.AddRepository<Route, EfCoreRouteRepository>();
options.AddRepository<Data, EfCoreDataRepository>();
options.AddRepository<Menu, EfCoreMenuRepository>();
options.AddRepository<UserMenu, EfCoreUserMenuRepository>();
options.AddRepository<RoleMenu, EfCoreRoleMenuRepository>();
options.AddRepository<Layout, EfCoreLayoutRepository>();
options.AddRepository<AppVersion, EfCoreVersionRepository>();
options.AddDefaultRepositories(includeAllEntities: true);

4
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/AppPlatformModelBuilderConfigurationOptions.cs → aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/EntityFrameworkCore/PlatformModelBuilderConfigurationOptions.cs

@ -3,9 +3,9 @@ using Volo.Abp.EntityFrameworkCore.Modeling;
namespace LINGYUN.Platform.EntityFrameworkCore
{
public class AppPlatformModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions
public class PlatformModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions
{
public AppPlatformModelBuilderConfigurationOptions(
public PlatformModelBuilderConfigurationOptions(
[NotNull] string tablePrefix = "",
[CanBeNull] string schema = null)
: base(

74
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/Layouts/EfCoreLayoutRepository.cs

@ -0,0 +1,74 @@
using LINGYUN.Platform.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Platform.Layouts
{
public class EfCoreLayoutRepository : EfCoreRepository<PlatformDbContext, Layout, Guid>, ILayoutRepository
{
public EfCoreLayoutRepository(IDbContextProvider<PlatformDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public virtual async Task<Layout> FindByNameAsync(
string name,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await DbSet
.IncludeDetails(includeDetails)
.Where(x => x.Name == name)
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<int> GetCountAsync(
PlatformType? platformType = null,
string filter = "",
CancellationToken cancellationToken = default)
{
return await DbSet
.WhereIf(platformType.HasValue, x => x.PlatformType == platformType.Value)
.WhereIf(!filter.IsNullOrWhiteSpace(), x =>
x.Name.Contains(filter) || x.DisplayName.Contains(filter) ||
x.Description.Contains(filter) || x.Redirect.Contains(filter))
.CountAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<Layout>> GetPagedListAsync(
PlatformType? platformType = null,
string filter = "",
string sorting = nameof(Layout.Name),
bool reverse = false,
bool includeDetails = false,
int skipCount = 0,
int maxResultCount = 10,
CancellationToken cancellationToken = default)
{
sorting ??= nameof(Layout.Name);
sorting = reverse ? sorting + " DESC" : sorting;
return await DbSet
.IncludeDetails(includeDetails)
.WhereIf(platformType.HasValue, x => x.PlatformType == platformType.Value)
.WhereIf(!filter.IsNullOrWhiteSpace(), x =>
x.Name.Contains(filter) || x.DisplayName.Contains(filter) ||
x.Description.Contains(filter) || x.Redirect.Contains(filter))
.OrderBy(sorting)
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public override IQueryable<Layout> WithDetails()
{
return GetQueryable().IncludeDetails();
}
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save