diff --git a/Infrastructure/Resolver/AntPathMatcher.cs b/Infrastructure/Resolver/AntPathMatcher.cs new file mode 100644 index 0000000..77073c0 --- /dev/null +++ b/Infrastructure/Resolver/AntPathMatcher.cs @@ -0,0 +1,59 @@ +using System; + +namespace ZR.Infrastructure.Resolver; + +public static class AntPathMatcher +{ + public static bool Match(string pattern, string value) + { + if (pattern == null || value == null) + return false; + + if (pattern == "**") + return true; + + var patternSegments = pattern.Split('/'); + var valueSegments = value.Split('/'); + + int patternIndex = 0; + int valueIndex = 0; + int patternWildcardIndex = -1; + int valueWildcardIndex = -1; + + while (valueIndex < valueSegments.Length) + { + if (patternIndex < patternSegments.Length && IsMatch(patternSegments[patternIndex], valueSegments[valueIndex])) + { + patternIndex++; + valueIndex++; + } + else if (patternWildcardIndex != -1) + { + patternIndex = patternWildcardIndex + 1; + valueIndex = ++valueWildcardIndex; + } + else + { + return false; + } + } + + while (patternIndex < patternSegments.Length && patternSegments[patternIndex] == "**") + { + patternIndex++; + } + + return patternIndex >= patternSegments.Length && valueIndex >= valueSegments.Length; + } + + private static bool IsMatch(string patternSegment, string valueSegment) + { + if (patternSegment == "*") + return true; + + if (patternSegment.StartsWith("{") && patternSegment.EndsWith("}")) + return true; // 支持占位符的匹配逻辑 + + return string.Equals(patternSegment, valueSegment, StringComparison.OrdinalIgnoreCase); + } +} \ No newline at end of file diff --git a/Infrastructure/Resolver/PropertyFilterContractResolver.cs b/Infrastructure/Resolver/PropertyFilterContractResolver.cs new file mode 100644 index 0000000..0f85e1f --- /dev/null +++ b/Infrastructure/Resolver/PropertyFilterContractResolver.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace ZR.Infrastructure.Resolver; + +public class PropertyFilterContractResolver : CamelCasePropertyNamesContractResolver +{ + private readonly HashSet _includedPaths; + private readonly HashSet _excludedPaths; + + public PropertyFilterContractResolver(IEnumerable includedPaths, IEnumerable excludedPaths) + { + _includedPaths = includedPaths.ToHashSet(); + _excludedPaths = excludedPaths.ToHashSet(); + } + + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + var properties = base.CreateProperties(type, memberSerialization); + + properties = properties.Where(p => IsIncluded(p) && !IsExcluded(p)).ToList(); + + return properties; + } + + private bool IsIncluded(JsonProperty property) + { + if (_includedPaths == null || _includedPaths.Count == 0) + return true; + + return _includedPaths.Any(path => AntPathMatcher.Match(path, property.PropertyName)); + } + + private bool IsExcluded(JsonProperty property) + { + if (_excludedPaths == null || _excludedPaths.Count == 0) + return false; + + return _excludedPaths.Any(path => AntPathMatcher.Match(path, property.PropertyName)); + } +} \ No newline at end of file diff --git a/ZR.Admin.Grpc/Extensions/GrpcServiceExtensions.cs b/ZR.Admin.Grpc/Extensions/GrpcServiceExtensions.cs new file mode 100644 index 0000000..dc2d442 --- /dev/null +++ b/ZR.Admin.Grpc/Extensions/GrpcServiceExtensions.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace ZR.Admin.Grpc.Extensions; + +public static class GrpcServiceExtensions +{ + public static void AddGrpcServiceConfiguration(this IServiceCollection services, IConfiguration configuration) + { + // services.AddTransient() + + services.AddGrpcClient(options => + { + options.Address = new Uri(configuration.GetValue("GrpcUrls:FindTeacher")); + }); + } +} \ No newline at end of file diff --git a/ZR.Admin.Grpc/Protos/block.proto b/ZR.Admin.Grpc/Protos/block.proto new file mode 100644 index 0000000..3ea6d99 --- /dev/null +++ b/ZR.Admin.Grpc/Protos/block.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +option csharp_namespace = "GrpcService1"; + +package block; + +service Block { + rpc GetBlock (BlockRequest) returns (BlockReply); +} + +message BlockRequest { + string in = 1; +} + +message BlockReply { + string out = 1; +} \ No newline at end of file diff --git a/ZR.Admin.Grpc/Protos/greet.proto b/ZR.Admin.Grpc/Protos/greet.proto new file mode 100644 index 0000000..6638c93 --- /dev/null +++ b/ZR.Admin.Grpc/Protos/greet.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +option csharp_namespace = "ZR.Admin.Grpc"; + +package greet; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply); +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings. +message HelloReply { + string message = 1; +} diff --git a/ZR.Admin.Grpc/ZR.Admin.Grpc.csproj b/ZR.Admin.Grpc/ZR.Admin.Grpc.csproj new file mode 100644 index 0000000..dbd25e7 --- /dev/null +++ b/ZR.Admin.Grpc/ZR.Admin.Grpc.csproj @@ -0,0 +1,22 @@ + + + + net7.0 + enable + enable + + + + + + + + + + + + + + + + diff --git a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs index d561f4f..316dbcb 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs @@ -140,7 +140,7 @@ namespace ZR.Admin.WebApi.Controllers.System public IActionResult GetRouters() { long uid = HttpContext.GetUId(); - var menus = sysMenuService.SelectMenuTreeByUserId(uid); + var menus = sysMenuService.SelectMenuTreeByUserId(uid); return SUCCESS(sysMenuService.BuildMenus(menus)); } diff --git a/ZR.Admin.WebApi/NLog.config b/ZR.Admin.WebApi/NLog.config index b72b504..92b8eba 100644 --- a/ZR.Admin.WebApi/NLog.config +++ b/ZR.Admin.WebApi/NLog.config @@ -4,7 +4,8 @@ xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd" autoReload="true" internalLogLevel="Info" - internalLogFile="nlog-internal.log"> + internalLogFile="nlog-internal.log" + throwConfigExceptions="true"> diff --git a/ZR.Admin.WebApi/Program.cs b/ZR.Admin.WebApi/Program.cs index cd79a89..dc77caa 100644 --- a/ZR.Admin.WebApi/Program.cs +++ b/ZR.Admin.WebApi/Program.cs @@ -4,12 +4,20 @@ using Microsoft.AspNetCore.DataProtection; using NLog.Web; using System.Text.Json; using BloomFilter.CSRedis.Configurations; +using Grpc.Net.Client; +using GrpcService1; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Redis; using Microsoft.Extensions.Options; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using ZR.Admin.Grpc; +using ZR.Admin.Grpc.Extensions; using ZR.Admin.WebApi.Extensions; using ZR.Infrastructure.Cache; +using ZR.Infrastructure.Resolver; using ZR.Infrastructure.WebExtensions; +using ZR.ServiceCore.Model; using ZR.ServiceCore.Services.IService; using ZR.ServiceCore.Signalr; using ZR.ServiceCore.SqlSugar; @@ -33,6 +41,8 @@ builder.Services.AddSwaggerGen(); builder.Services.AddSingleton(); // 跨域配置 builder.Services.AddCors(builder.Configuration); +// Grpc +builder.Services.AddGrpc(); // 显示logo // builder.Services.AddLogo(); //消除Error unprotecting the session cookie警告 @@ -100,7 +110,15 @@ builder.Services.AddSignalR() options.PayloadSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; }); builder.Services.AddSwaggerConfig(); - +// using var channel = GrpcChannel.ForAddress("https://localhost:7025"); +// var client = new Greeter.GreeterClient(channel); +// var reply = await client.SayHelloAsync(new HelloRequest { Name = "GreeterClient" }); +// Console.WriteLine("Greeting: " + reply.Message); +// +// var blockClient = new Block.BlockClient(channel); +// var blockReply = await blockClient.GetBlockAsync(new BlockRequest { In = "asads" }); +// Console.WriteLine("BlockReply: " + blockReply.Out); +builder.Services.AddGrpcServiceConfiguration(builder.Configuration); var app = builder.Build(); InternalApp.ServiceProvider = app.Services; InternalApp.Configuration = builder.Configuration; @@ -179,5 +197,13 @@ using (var serviceScope = app.Services.CreateScope()) var pol = await ipPolicyStore.GetAsync(optionsAccessor.Value.IpPolicyPrefix); pol.IpRules.AddRange(ipRateLimitPolicies.Adapt>()); await ipPolicyStore.SetAsync(optionsAccessor.Value.IpPolicyPrefix, pol); + + var greeterClient = services.GetRequiredService(); + var helloReply = await greeterClient.SayHelloAsync(new HelloRequest + { + Name = "gree" + }); + Console.WriteLine(helloReply); } + app.Run(); \ No newline at end of file diff --git a/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj b/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj index 6a9ff24..57a3d9a 100644 --- a/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj +++ b/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj @@ -10,6 +10,7 @@ + diff --git a/ZRAdmin.sln b/ZRAdmin.sln index 0c5700e..429aee6 100644 --- a/ZRAdmin.sln +++ b/ZRAdmin.sln @@ -21,6 +21,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZR.CodeGenerator", "ZR.Code EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZR.ServiceCore", "ZR.ServiceCore\ZR.ServiceCore.csproj", "{4E2CC4E4-F109-4876-8498-912E13905765}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZR.Admin.Grpc", "ZR.Admin.Grpc\ZR.Admin.Grpc.csproj", "{41169953-F3CB-4152-894D-09C541805AD4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -63,6 +65,10 @@ Global {4E2CC4E4-F109-4876-8498-912E13905765}.Debug|Any CPU.Build.0 = Debug|Any CPU {4E2CC4E4-F109-4876-8498-912E13905765}.Release|Any CPU.ActiveCfg = Release|Any CPU {4E2CC4E4-F109-4876-8498-912E13905765}.Release|Any CPU.Build.0 = Release|Any CPU + {41169953-F3CB-4152-894D-09C541805AD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {41169953-F3CB-4152-894D-09C541805AD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {41169953-F3CB-4152-894D-09C541805AD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {41169953-F3CB-4152-894D-09C541805AD4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE