From 6c0058d15ab61956b806f62a2b576ffd5d723ed9 Mon Sep 17 00:00:00 2001 From: sunpengfei <i@angelzzz.com> Date: 星期五, 08 八月 2025 11:16:21 +0800 Subject: [PATCH] fix:bug --- FlexJobApi.Core/FlexJobApiCoreStartup.cs | 5 FlexJobApi.FlexJobServer.Test/FlexJobApi.FlexJobServer.Test.csproj | 3 FlexJobApi.FlexJobServer.Test/Program.cs | 1 FlexJobApi.FlexJobServer.Test/Startup.cs | 71 ++++++++++++++ FlexJobApi.Core/Utils/ResourceUtils/ResourceUtils.cs | 45 +-------- FlexJobApi.Core/Utils/ResourceUtils/ResourceModel.cs | 21 ++++ FlexJobApi.Core/FlexJobApi.Core.xml | 24 +++- FlexJobApi.Core/Models/FlexJobServer/Tasks/Repositories/TaskInfoRepository.cs | 5 FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpUtils.cs | 81 ++++++++++++++++ FlexJobApi.FlexJobServer.Test/Tasks/TaskUnitTest.cs | 9 + 10 files changed, 212 insertions(+), 53 deletions(-) diff --git a/FlexJobApi.Core/FlexJobApi.Core.xml b/FlexJobApi.Core/FlexJobApi.Core.xml index 6f33937..161a24d 100644 --- a/FlexJobApi.Core/FlexJobApi.Core.xml +++ b/FlexJobApi.Core/FlexJobApi.Core.xml @@ -5640,6 +5640,23 @@ </summary> <returns></returns> </member> + <member name="M:FlexJobApi.Core.ResourceHttpUtils.SendHttpAsync``2(``0,FlexJobApi.Core.IResourceHttpProvider)"> + <summary> + 鍙戦�丠TTP璇锋眰 + </summary> + <typeparam name="TRequest"></typeparam> + <typeparam name="TResponse"></typeparam> + <param name="request"></param> + <param name="provider"></param> + <returns></returns> + </member> + <member name="M:FlexJobApi.Core.ResourceHttpUtils.GetHealthyServiceDomain(FlexJobApi.Core.ResourceModel)"> + <summary> + 鑾峰彇鍋ュ悍鏈嶅姟鍩熷悕 + </summary> + <param name="resource"></param> + <returns></returns> + </member> <member name="P:FlexJobApi.Core.ResourceModel.TraceId"> <summary> 璺熻釜Id @@ -5798,13 +5815,6 @@ <typeparam name="TResponse"></typeparam> <param name="request"></param> <param name="provider"></param> - <returns></returns> - </member> - <member name="M:FlexJobApi.Core.ResourceUtils.GetHealthyServiceDomain(FlexJobApi.Core.Resource)"> - <summary> - 鑾峰彇鍋ュ悍鏈嶅姟鍩熷悕 - </summary> - <param name="resource"></param> <returns></returns> </member> <member name="M:FlexJobApi.Core.ResourceUtils.BuildDynamicControllersAsync"> diff --git a/FlexJobApi.Core/FlexJobApiCoreStartup.cs b/FlexJobApi.Core/FlexJobApiCoreStartup.cs index c677577..1ffa807 100644 --- a/FlexJobApi.Core/FlexJobApiCoreStartup.cs +++ b/FlexJobApi.Core/FlexJobApiCoreStartup.cs @@ -43,14 +43,15 @@ services.AddConfigurableOptions<AliyunOptions>(); - services.AddHttpRemote(); - services.AddComponent<ConsulServiceComponent>(); services.AddComponent<EventBusServiceComponent>(); services.AddComponent<DistributedCacheServiceComponent>(); + services.AddHttpRemote(); + services.AddSingleton<ResourceHttpUtils>(); + services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(App.Assemblies.ToArray())); services.AddHostedService<XmlDocBuildHostedService>(); diff --git a/FlexJobApi.Core/Models/FlexJobServer/Tasks/Repositories/TaskInfoRepository.cs b/FlexJobApi.Core/Models/FlexJobServer/Tasks/Repositories/TaskInfoRepository.cs index 2f73592..103ccbe 100644 --- a/FlexJobApi.Core/Models/FlexJobServer/Tasks/Repositories/TaskInfoRepository.cs +++ b/FlexJobApi.Core/Models/FlexJobServer/Tasks/Repositories/TaskInfoRepository.cs @@ -25,7 +25,10 @@ logier = logier ?? JwtUtils.GetCurrentLogier(); return rep.AsQueryable().AsNoTracking() .OrderBy(it => it.BeginTime) - .Where(it => it.EnterpriseId == logier.EnterpriseId); + .Where(it => + logier.Type == EnumUserType.Enterprise + ? it.EnterpriseId == logier.EnterpriseId + : true); } } } diff --git a/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpUtils.cs b/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpUtils.cs new file mode 100644 index 0000000..db7a2db --- /dev/null +++ b/FlexJobApi.Core/Utils/ResourceUtils/ResourceHttpUtils.cs @@ -0,0 +1,81 @@ +锘縰sing Consul; +using Furion; +using Furion.FriendlyException; +using Furion.HttpRemote; +using Microsoft.Extensions.Caching.Distributed; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FlexJobApi.Core +{ + public class ResourceHttpUtils + { + private readonly IDistributedCache distributedCache; + private readonly IHttpRemoteService httpRemoteService; + private readonly IConsulClient consulClient; + + public ResourceHttpUtils( + IDistributedCache distributedCache, + IHttpRemoteService httpRemoteService, + IConsulClient consulClient) + { + this.distributedCache = distributedCache; + this.httpRemoteService = httpRemoteService; + this.consulClient = consulClient; + } + + /// <summary> + /// 鍙戦�丠TTP璇锋眰 + /// </summary> + /// <typeparam name="TRequest"></typeparam> + /// <typeparam name="TResponse"></typeparam> + /// <param name="request"></param> + /// <param name="provider"></param> + /// <returns></returns> + public async Task<TResponse> SendHttpAsync<TRequest, TResponse>( + TRequest request, + IResourceHttpProvider provider = null) + where TRequest : class, new() + { + var requestTypeFullName = typeof(TRequest).FullName; + + var jsonResourceModels = await distributedCache.GetStringAsync($"ResourceModel|{requestTypeFullName}"); + var resource = jsonResourceModels.JsonTo<ResourceModel>(); + var domain = await GetHealthyServiceDomain(resource); + var builder = HttpRequestBuilder.Create(resource.GetHttpMethod(), $"{domain}{resource.Route}"); + if (resource.Method == EnumResourceMethod.Get) + builder = builder.WithQueryParameters(request); + else + builder = builder.SetJsonContent(request); + provider = provider ?? new DefaultResourceHttpProvider(); + builder = provider.AddAuthentication(builder); + var response = await provider.SendAsAsync<TResponse>(httpRemoteService, builder); + return response; + } + + /// <summary> + /// 鑾峰彇鍋ュ悍鏈嶅姟鍩熷悕 + /// </summary> + /// <param name="resource"></param> + /// <returns></returns> + public async Task<string> GetHealthyServiceDomain(ResourceModel resource) + { + var queryResult = await consulClient.Health.Service(resource.ServiceName, null, true); + if (queryResult.StatusCode != System.Net.HttpStatusCode.OK) + throw Oops.Oh(EnumErrorCodeType.s404, $"寰湇鍔resource.Service}"); + + var domains = queryResult.Response + .Select(s => $"http://{s.Service.Address}:{s.Service.Port}") + .ToList(); + if (domains.IsNull()) + throw Oops.Oh(EnumErrorCodeType.s404, $"寰湇鍔resource.Service}"); + // 杞閫夋嫨瀹炰緥 + int randomIndex = new Random().Next(domains.Count); + return domains[randomIndex]; + } + + } +} diff --git a/FlexJobApi.Core/Utils/ResourceUtils/ResourceModel.cs b/FlexJobApi.Core/Utils/ResourceUtils/ResourceModel.cs index e1e113d..cf9d314 100644 --- a/FlexJobApi.Core/Utils/ResourceUtils/ResourceModel.cs +++ b/FlexJobApi.Core/Utils/ResourceUtils/ResourceModel.cs @@ -1,7 +1,9 @@ -锘縰sing System; +锘縰sing Furion.FriendlyException; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Net.Http; using System.Text; using System.Threading.Tasks; @@ -103,5 +105,22 @@ /// 鍝嶅簲绫诲瀷鍏ㄥ悕 /// </summary> public string ResponseTypeFullName { get; set; } + + public HttpMethod GetHttpMethod() + { + switch (Method) + { + case EnumResourceMethod.Get: + return HttpMethod.Get; + case EnumResourceMethod.Post: + return HttpMethod.Post; + case EnumResourceMethod.Put: + return HttpMethod.Put; + case EnumResourceMethod.Delete: + return HttpMethod.Delete; + default: + throw Oops.Oh(EnumErrorCodeType.s400, "涓嶆敮鎸佺殑璇锋眰绫诲瀷"); + } + } } } diff --git a/FlexJobApi.Core/Utils/ResourceUtils/ResourceUtils.cs b/FlexJobApi.Core/Utils/ResourceUtils/ResourceUtils.cs index d1749ca..cc1216c 100644 --- a/FlexJobApi.Core/Utils/ResourceUtils/ResourceUtils.cs +++ b/FlexJobApi.Core/Utils/ResourceUtils/ResourceUtils.cs @@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Routing; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; @@ -44,48 +45,12 @@ /// <param name="request"></param> /// <param name="provider"></param> /// <returns></returns> - public static async Task<TResponse> SendHttpAsync<TRequest, TResponse>( + public static Task<TResponse> SendHttpAsync<TRequest, TResponse>( TRequest request, IResourceHttpProvider provider = null) where TRequest : class, new() { - var requestTypeFullName = typeof(TRequest).FullName; - var resource = await Db.GetRepository<Resource>().AsQueryable().AsNoTracking() - .Where(it => !it.IsExpired && it.RequestTypeFullName == requestTypeFullName) - .FirstOrDefaultAsync(); - var domain = await GetHealthyServiceDomain(resource); - var httpRemoteService = App.GetRequiredService<IHttpRemoteService>(); - var builder = HttpRequestBuilder.Create(resource.GetHttpMethod(), $"{domain}{resource.Route}"); - if (resource.Method == EnumResourceMethod.Get) - builder = builder.WithQueryParameters(request); - else - builder = builder.SetJsonContent(request); - provider = provider ?? new DefaultResourceHttpProvider(); - builder = provider.AddAuthentication(builder); - var response = await provider.SendAsAsync<TResponse>(httpRemoteService, builder); - return response; - } - - /// <summary> - /// 鑾峰彇鍋ュ悍鏈嶅姟鍩熷悕 - /// </summary> - /// <param name="resource"></param> - /// <returns></returns> - public static async Task<string> GetHealthyServiceDomain(Resource resource) - { - var client = App.GetRequiredService<IConsulClient>(); - var queryResult = await client.Health.Service(resource.ServiceName, null, true); - if (queryResult.StatusCode != System.Net.HttpStatusCode.OK) - throw Oops.Oh(EnumErrorCodeType.s404, $"寰湇鍔resource.Service}"); - - var domains = queryResult.Response - .Select(s => $"http://{s.Service.Address}:{s.Service.Port}") - .ToList(); - if (domains.IsNull()) - throw Oops.Oh(EnumErrorCodeType.s404, $"寰湇鍔resource.Service}"); - // 杞閫夋嫨瀹炰緥 - int randomIndex = new Random().Next(domains.Count); - return domains[randomIndex]; + return App.GetRequiredService<ResourceHttpUtils>().SendHttpAsync<TRequest, TResponse>(request, provider); } /// <summary> @@ -152,9 +117,9 @@ model.ResponseTypeName = responseType.GetCSharpFriendlyName(); model.ResponseTypeFullName = responseType.FullName; } - - models.Add(model); + + await App.GetRequiredService<IDistributedCache>().SetStringAsync($"ResourceModel|{model.RequestTypeFullName}", model.ToJson()); } } diff --git a/FlexJobApi.FlexJobServer.Test/FlexJobApi.FlexJobServer.Test.csproj b/FlexJobApi.FlexJobServer.Test/FlexJobApi.FlexJobServer.Test.csproj index 38469f4..59ab904 100644 --- a/FlexJobApi.FlexJobServer.Test/FlexJobApi.FlexJobServer.Test.csproj +++ b/FlexJobApi.FlexJobServer.Test/FlexJobApi.FlexJobServer.Test.csproj @@ -17,8 +17,9 @@ <ItemGroup> <PackageReference Include="coverlet.collector" Version="6.0.2" /> + <PackageReference Include="Furion.Xunit" Version="4.9.7.108" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" /> - <PackageReference Include="xunit" Version="2.9.2" /> + <PackageReference Include="xunit" Version="2.9.3" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" /> </ItemGroup> diff --git a/FlexJobApi.FlexJobServer.Test/Program.cs b/FlexJobApi.FlexJobServer.Test/Program.cs new file mode 100644 index 0000000..611ed5a --- /dev/null +++ b/FlexJobApi.FlexJobServer.Test/Program.cs @@ -0,0 +1 @@ +Serve.Run(RunOptions.Default.WithArgs(args)); \ No newline at end of file diff --git a/FlexJobApi.FlexJobServer.Test/Startup.cs b/FlexJobApi.FlexJobServer.Test/Startup.cs new file mode 100644 index 0000000..9d58144 --- /dev/null +++ b/FlexJobApi.FlexJobServer.Test/Startup.cs @@ -0,0 +1,71 @@ +锘縰sing Consul; +using FlexJobApi.Core; +using Furion; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FlexJobApi.FlexJobServer.Test +{ + public class Startup : AppStartup + { + public void ConfigureServices(IServiceCollection services, IConfiguration config) + { + services.AddSingleton<IConsulClient, ConsulClient>(p => new ConsulClient(options => + { + var address = config["Consul:Address"] ?? "http://localhost:8500"; + options.Address = new Uri(address); + })); + services.AddComponent<DistributedCacheServiceComponent>(); + services.AddHttpRemote(); + services.AddSingleton<ResourceHttpUtils>(); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IConfiguration config) + { + var consulClient = app.ApplicationServices.GetRequiredService<IConsulClient>(); + var lifetime = app.ApplicationServices.GetRequiredService<IHostApplicationLifetime>(); + + // 鏈嶅姟閰嶇疆锛堜粠appsettings.json璇诲彇锛� + var serviceName = config["Consul:ServiceName"] ?? "UnknownService"; + var serviceHost = config["Consul:ServiceIP"] ?? "localhost"; + var servicePort = int.Parse(config["Consul:ServicePort"]); // 鎴栫洿鎺ョ敤鍚姩绔彛 + + // 鏈嶅姟鍞竴ID锛堥伩鍏嶅悓涓�鏈嶅姟澶氬疄渚嬪啿绐侊級 + var serviceId = $"{serviceName}-{serviceHost}-{servicePort}"; + + // 鏈嶅姟娉ㄥ唽淇℃伅 + var registration = new AgentServiceRegistration + { + ID = serviceId, + Name = serviceName, + Address = serviceHost, + Port = servicePort, + // 鍋ュ悍妫�鏌ラ厤缃� + Check = new AgentServiceCheck + { + HTTP = $"http://{serviceHost}:{servicePort}{config["Consul:ServiceHealthCheck"]}", + Interval = TimeSpan.FromSeconds(10), + Timeout = TimeSpan.FromSeconds(5), + DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(30) + } + }; + + // 娉ㄥ唽鏈嶅姟 + consulClient.Agent.ServiceRegister(registration).Wait(); + + // 搴旂敤鍋滄鏃舵敞閿�鏈嶅姟 + lifetime.ApplicationStopping.Register(() => + { + consulClient.Agent.ServiceDeregister(serviceId).Wait(); + }); + } + } +} diff --git a/FlexJobApi.FlexJobServer.Test/Tasks/TaskUnitTest.cs b/FlexJobApi.FlexJobServer.Test/Tasks/TaskUnitTest.cs index 3a93b69..4d96e1e 100644 --- a/FlexJobApi.FlexJobServer.Test/Tasks/TaskUnitTest.cs +++ b/FlexJobApi.FlexJobServer.Test/Tasks/TaskUnitTest.cs @@ -5,10 +5,17 @@ { public class TaskUnitTest { + private readonly ResourceHttpUtils http; + + public TaskUnitTest(ResourceHttpUtils http) + { + this.http = http; + } + [Fact] public async Task Test1() { - var categories = await ResourceUtils.SendHttpAsync< + var categories = await http.SendHttpAsync< GetDictionaryCategorySelectQuery, FriendlyResult<SelectOption<Guid, GetDictionaryCategorySelectQueryOption>>>( new GetDictionaryCategorySelectQuery()); -- Gitblit v1.9.1