diff --git a/.editorconfig b/.editorconfig
index 6300f1e..3698777 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,11 +1,14 @@
+# Rules in this file were initially inferred by Visual Studio IntelliCode from the D:\Projects\MicroService\CRM\Vue\abp-next-admin\aspnet-core codebase based on best match to current usage at 2022-01-07
+# There already existed an .editorconfig file in this directory. Copy rules from this .editorconfig.inferred file to the existing .editorconfig file as desired to have them take effect at this location.
+# You can modify the rules from these initially generated values to suit your own policies
+# You can learn more about editorconfig here: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference
[*.cs]
-#Namespace settings
-csharp_style_namespace_declarations = file_scoped
-dotnet_diagnostic.IDE0161.severity = warning
#Core editorconfig formatting - indentation
+#use soft tabs (spaces) for indentation
+indent_style = space
#Formatting - indentation options
@@ -20,9 +23,17 @@ csharp_indent_switch_labels = true
csharp_new_line_before_catch = true
#place else statements on a new line
csharp_new_line_before_else = true
+#require members of anonymous types to be on separate lines
+csharp_new_line_before_members_in_anonymous_types = true
+#require members of object initializers to be on the same line
+csharp_new_line_before_members_in_object_initializers = false
+#require braces to be on a new line for methods, control_blocks, types, lambdas, object_collection_array_initializers, anonymous_methods, and anonymous_types (also known as "Allman" style)
+csharp_new_line_before_open_brace = methods, control_blocks, types, lambdas, object_collection_array_initializers, anonymous_methods, anonymous_types
#Formatting - organize using options
+#do not place System.* using directives before other using directives
+dotnet_sort_system_directives_first = false
#Formatting - spacing options
@@ -79,6 +90,8 @@ dotnet_style_predefined_type_for_member_access = true:suggestion
csharp_prefer_simple_default_expression = true:suggestion
#prefer objects to be initialized using object initializers when possible
dotnet_style_object_initializer = true:suggestion
+#prefer inferred anonymous type member names
+dotnet_style_prefer_inferred_anonymous_type_member_names = false:suggestion
#Style - implicit and explicit types
@@ -96,6 +109,8 @@ dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
#Style - Miscellaneous preferences
+#prefer anonymous functions over local functions
+csharp_style_pattern_local_over_anonymous_function = false:suggestion
#Style - modifier options
@@ -105,6 +120,7 @@ dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggest
#Style - Modifier preferences
#when this rule is set to a list of modifiers, prefer the specified ordering.
+csharp_preferred_modifier_order = public,private,protected,internal,async,virtual,readonly,static,override,abstract:suggestion
#Style - Pattern matching
@@ -120,3 +136,23 @@ dotnet_style_qualification_for_method = false:suggestion
#prefer properties not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_property = false:suggestion
csharp_style_namespace_declarations=file_scoped:silent
+
+#### 命名样式 ####
+
+# 命名规则
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.private_or_internal_field_should_be_prefix_.severity = suggestion
+dotnet_naming_rule.private_or_internal_field_should_be_prefix_.symbols = private_or_internal_field
+dotnet_naming_rule.private_or_internal_field_should_be_prefix_.style = prefix_
\ No newline at end of file
diff --git a/Sanhe.Abp.Framework.sln b/Sanhe.Abp.Framework.sln
index 00d2952..3758ae4 100644
--- a/Sanhe.Abp.Framework.sln
+++ b/Sanhe.Abp.Framework.sln
@@ -31,6 +31,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sanhe.Abp.Features.LimitVal
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sanhe.Abp.Features.LimitValidation.Redis.Client", "modules\common\Sanhe.Abp.Features.LimitValidation.Redis.Client\Sanhe.Abp.Features.LimitValidation.Redis.Client.csproj", "{97DDB479-946C-489D-9089-6EAEBFEE97C6}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "solution items", "solution items", "{8DAEBF3C-8948-44EF-AB7C-8662CCACD2C6}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
diff --git a/services/book-store/BookStore.csproj b/services/book-store/BookStore.csproj
index 9a2ffdd..246b590 100644
--- a/services/book-store/BookStore.csproj
+++ b/services/book-store/BookStore.csproj
@@ -92,6 +92,7 @@
+
diff --git a/services/book-store/BookStoreModule.cs b/services/book-store/BookStoreModule.cs
index 6f1fb44..9f3cee4 100644
--- a/services/book-store/BookStoreModule.cs
+++ b/services/book-store/BookStoreModule.cs
@@ -11,6 +11,7 @@ using Microsoft.OpenApi.Models;
using Sanhe.Abp.AspNetCore.Mvc.Wrapper;
using Sanhe.Abp.ExceptionHandling;
using Sanhe.Abp.ExceptionHandling.Emailing;
+using Sanhe.Abp.Features.LimitValidation.Redis;
using Sanhe.Abp.Wrapper;
using StackExchange.Redis;
using System;
@@ -47,6 +48,7 @@ using Volo.Abp.PermissionManagement.HttpApi;
using Volo.Abp.PermissionManagement.Identity;
using Volo.Abp.SettingManagement;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
+using Volo.Abp.Settings;
using Volo.Abp.Swashbuckle;
using Volo.Abp.TenantManagement;
using Volo.Abp.TenantManagement.EntityFrameworkCore;
@@ -105,7 +107,8 @@ namespace BookStore;
typeof(AbpSettingManagementHttpApiModule),
typeof(AbpAspNetCoreMvcWrapperModule),
- typeof(AbpEmailingExceptionHandlingModule)
+ typeof(AbpEmailingExceptionHandlingModule),
+ typeof(AbpFeaturesValidationRedisModule)
)]
public class BookStoreModule : AbpModule
{
@@ -134,6 +137,11 @@ public class BookStoreModule : AbpModule
options.IsEnabled = true;
options.IgnoreNamespaces.Clear();
});
+ // limit
+ Configure(options =>
+ {
+ options.Configuration = "127.0.0.1:6379";
+ });
ConfigureExceptionHandling();
ConfigureBundles();
ConfigureMultiTenancy();
@@ -175,6 +183,7 @@ public class BookStoreModule : AbpModule
// options.DefaultReceiveEmail = "";
});
}
+
private void ConfigureBundles()
{
Configure(options =>
@@ -228,7 +237,7 @@ public class BookStoreModule : AbpModule
options.DefaultResourceType = typeof(BookStoreResource);
- options.Languages.Add(new LanguageInfo("en", "en", "English"));
+ //options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
});
@@ -255,7 +264,7 @@ public class BookStoreModule : AbpModule
{
Configure(options =>
{
- options.ConventionalControllers.Create(typeof(BookStoreModule).Assembly);
+ //options.ConventionalControllers.Create(typeof(BookStoreModule).Assembly);
});
}
@@ -339,12 +348,14 @@ public class BookStoreModule : AbpModule
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
+ app.ApplicationServices.GetService().Get(LocalizationSettingNames.DefaultLanguage).DefaultValue = "zh-Hans";
+
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
- app.UseAbpRequestLocalization();
+ app.UseAbpRequestLocalization(optios => optios.SetDefaultCulture("zh-hans"));
if (!env.IsDevelopment())
{
diff --git a/services/book-store/Controllers/LimitValidationController.cs b/services/book-store/Controllers/LimitValidationController.cs
new file mode 100644
index 0000000..5fa477c
--- /dev/null
+++ b/services/book-store/Controllers/LimitValidationController.cs
@@ -0,0 +1,23 @@
+using BookStore.Services;
+using Microsoft.AspNetCore.Mvc;
+using System.Threading.Tasks;
+using Volo.Abp.AspNetCore.Mvc;
+
+namespace BookStore.Controllers;
+
+[Route("api/limit-validation")]
+public class LimitValidationController : AbpControllerBase, ILimitValidationAppService
+{
+ private readonly ILimitValidationAppService _service;
+
+ public LimitValidationController(ILimitValidationAppService service)
+ {
+ _service = service;
+ }
+
+ [HttpGet]
+ public Task GetAsync()
+ {
+ return _service.GetAsync();
+ }
+}
diff --git a/services/book-store/Features/FakeFeatureDefinitionProvider.cs b/services/book-store/Features/FakeFeatureDefinitionProvider.cs
new file mode 100644
index 0000000..e071920
--- /dev/null
+++ b/services/book-store/Features/FakeFeatureDefinitionProvider.cs
@@ -0,0 +1,24 @@
+using Volo.Abp.Features;
+using Volo.Abp.Validation.StringValues;
+
+namespace BookStore.Features;
+
+public class FakeFeatureDefinitionProvider : FeatureDefinitionProvider
+{
+ public override void Define(IFeatureDefinitionContext context)
+ {
+ var featureGroup = context.AddGroup(FakeFeatureNames.GroupName);
+ featureGroup.AddFeature(
+ name: FakeFeatureNames.ClassLimitFeature,
+ defaultValue: 1000.ToString(),
+ valueType: new ToggleStringValueType(new NumericValueValidator(1, 1000)));
+ featureGroup.AddFeature(
+ name: FakeFeatureNames.MethodLimitFeature,
+ defaultValue: 3.ToString(),
+ valueType: new ToggleStringValueType(new NumericValueValidator(1, 1000)));
+ featureGroup.AddFeature(
+ name: FakeFeatureNames.IntervalFeature,
+ defaultValue: 1.ToString(), // 限制周期
+ valueType: new ToggleStringValueType(new NumericValueValidator(1, 1000)));
+ }
+}
diff --git a/services/book-store/Features/FakeFeatureNames.cs b/services/book-store/Features/FakeFeatureNames.cs
new file mode 100644
index 0000000..5a969ec
--- /dev/null
+++ b/services/book-store/Features/FakeFeatureNames.cs
@@ -0,0 +1,12 @@
+namespace BookStore.Features;
+
+public static class FakeFeatureNames
+{
+ public const string GroupName = "FakeFeature.Tests";
+ // 类型限制调用次数功能名称
+ public const string ClassLimitFeature = GroupName + ".LimitFeature";
+ // 方法限制调用次数功能名称
+ public const string MethodLimitFeature = GroupName + ".MethodLimitFeature";
+ // 限制调用间隔功能名称
+ public const string IntervalFeature = GroupName + ".IntervalFeature";
+}
\ No newline at end of file
diff --git a/services/book-store/Services/ILimitValidationAppService.cs b/services/book-store/Services/ILimitValidationAppService.cs
new file mode 100644
index 0000000..a6add32
--- /dev/null
+++ b/services/book-store/Services/ILimitValidationAppService.cs
@@ -0,0 +1,9 @@
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+
+namespace BookStore.Services;
+
+public interface ILimitValidationAppService : IApplicationService
+{
+ Task GetAsync();
+}
diff --git a/services/book-store/Services/LimitValidationAppService.cs b/services/book-store/Services/LimitValidationAppService.cs
new file mode 100644
index 0000000..09901bc
--- /dev/null
+++ b/services/book-store/Services/LimitValidationAppService.cs
@@ -0,0 +1,15 @@
+using BookStore.Features;
+using Sanhe.Abp.Features.LimitValidation;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+
+namespace BookStore.Services;
+
+public class LimitValidationAppService : ApplicationService, ILimitValidationAppService
+{
+ [RequiresLimitFeature(FakeFeatureNames.MethodLimitFeature, FakeFeatureNames.IntervalFeature, LimitPolicy.Minute)]
+ public Task GetAsync()
+ {
+ return Task.FromResult(0);
+ }
+}
diff --git a/services/book-store/appsettings.json b/services/book-store/appsettings.json
index 13256ff..e34d48a 100644
--- a/services/book-store/appsettings.json
+++ b/services/book-store/appsettings.json
@@ -8,6 +8,9 @@
"ConnectionStrings": {
"Default": "Host=localhost;Port=5432;Database=BookStore;User ID=postgres;Password=123456;"
},
+ "Settings": {
+ "Abp.Localization.DefaultLanguage": "zh-Hans"
+ },
"Redis": {
"Configuration": "127.0.0.1"
},