From d997afbfb26532dfbffcb569757e1be8fdd75088 Mon Sep 17 00:00:00 2001
From: sunpengfei <i@angelzzz.com>
Date: 星期四, 11 九月 2025 13:24:00 +0800
Subject: [PATCH] feat:开发

---
 FlexJobApi.Core/Utils/ResourceUtils/ResourceUtils.cs |  195 +++++++++++++++++++++---------------------------
 1 files changed, 85 insertions(+), 110 deletions(-)

diff --git a/FlexJobApi.Core/Utils/ResourceUtils/ResourceUtils.cs b/FlexJobApi.Core/Utils/ResourceUtils/ResourceUtils.cs
index 9b51203..42d58a1 100644
--- a/FlexJobApi.Core/Utils/ResourceUtils/ResourceUtils.cs
+++ b/FlexJobApi.Core/Utils/ResourceUtils/ResourceUtils.cs
@@ -6,6 +6,8 @@
 using Furion.DynamicApiController;
 using Furion.FriendlyException;
 using Furion.HttpRemote;
+using Furion.Logging;
+using Furion.Logging.Extensions;
 using Mapster;
 using MediatR;
 using Microsoft.AspNetCore.Mvc;
@@ -13,6 +15,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;
@@ -36,87 +39,6 @@
     /// </summary>
     public static class ResourceUtils
     {
-        /// <summary>
-        /// 鍙戦�丠TTP璇锋眰
-        /// </summary>
-        /// <typeparam name="TRequest"></typeparam>
-        /// <typeparam name="TResponse"></typeparam>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        public static async Task<TResponse> SendHttpAsync<TRequest, TResponse>(TRequest request)
-            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 token = App.HttpContext.Request.Headers["Authorization"].ToString();
-            var refreshToken = App.HttpContext.Request.Headers["X-Authorization"].ToString();
-            TResponse response;
-            switch (resource.Method)
-            {
-                case EnumResourceMethod.Get:
-                    response = await httpRemoteService.GetAsAsync<TResponse>(
-                        $"{domain}{resource.Route}",
-                        it =>
-                            it.WithQueryParameters(request)
-                            .AddAuthentication(new AuthenticationHeaderValue("Authorization", token))
-                            .AddAuthentication(new AuthenticationHeaderValue("X-Authorization", refreshToken)));
-                    break;
-                case EnumResourceMethod.Post:
-                    response = await httpRemoteService.PostAsAsync<TResponse>(
-                        $"{domain}{resource.Route}",
-                        it =>
-                            it.SetJsonContent(request)
-                            .WithHeader("Authorization", token)
-                            .WithHeader("X-Authorization", refreshToken));
-                    break;
-                case EnumResourceMethod.Put:
-                    response = await httpRemoteService.PutAsAsync<TResponse>(
-                        $"{domain}{resource.Route}",
-                        it =>
-                            it.SetJsonContent(request)
-                            .AddAuthentication(new AuthenticationHeaderValue("Authorization", token))
-                            .AddAuthentication(new AuthenticationHeaderValue("X-Authorization", refreshToken)));
-                    break;
-                case EnumResourceMethod.Delete:
-                    response = await httpRemoteService.DeleteAsAsync<TResponse>(
-                        $"{domain}{resource.Route}",
-                        it =>
-                            it.SetJsonContent(request)
-                            .AddAuthentication(new AuthenticationHeaderValue("Authorization", token))
-                            .AddAuthentication(new AuthenticationHeaderValue("X-Authorization", refreshToken)));
-                    break;
-                default:
-                    throw Oops.Oh(EnumErrorCodeType.s400, $"涓嶆敮鎸佽姹傛柟寮弡resource.Method}");
-            }
-            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];
-        }
-
         /// <summary>
         /// 鐢熸垚鍔ㄦ�佹帶鍒跺櫒
         /// </summary>
@@ -149,16 +71,17 @@
                     var model = new ResourceModel();
                     model.TraceId = traceId;
                     model.ApplicationName = resourceService.ApplicationName;
-                    model.Controller = controller;
+                    model.ControllerName = resourceController.ControllerName;
                     model.ControllerSummary = resourceControllers.GetDescription(controller);
                     model.ActionName = Regex.Replace(request.Name, @"(Command|Query)$", "", RegexOptions.None);
                     model.ActionSummary = requestXmlDoc?.Summary;
-                    model.Service = resourceController.Service;
                     model.ServiceName = resourceService.ServiceName;
                     model.RouteArea = resourceService.RouteArea;
-                    model.Route = $"/api/{resourceService.RouteArea ?? "main"}/{controller}/{model.ActionName}";
+                    model.Route = $"/api/{resourceService.RouteArea ?? "main"}/{model.ControllerName}/{model.ActionName}";
                     model.Method =
-                        request.BaseType?.IsGenericType == true && request.BaseType.GetGenericTypeDefinition() == typeof(PagedListQuery<,>)
+                        resourceAttribute.Method != EnumResourceMethod.None
+                        ? resourceAttribute.Method
+                        : request.BaseType?.IsGenericType == true && request.BaseType.GetGenericTypeDefinition() == typeof(PagedListQuery<,>)
                         ? EnumResourceMethod.Post
                         : new List<string> { "Post", "Add", "Create", "Insert", "Submit" }.Any(it => request.Name.StartsWith(it, StringComparison.OrdinalIgnoreCase))
                         ? EnumResourceMethod.Post
@@ -169,6 +92,15 @@
                         : new List<string> { "Delete", "Remove ", "Clear" }.Any(it => request.Name.StartsWith(it, StringComparison.OrdinalIgnoreCase))
                         ? EnumResourceMethod.Delete
                         : EnumResourceMethod.Post;
+                    model.FileUpload = resourceAttribute.FileUpload;
+                    if (model.FileUpload)
+                    {
+                        model.IsFromForm = true;
+                    }
+                    else
+                    {
+                        model.IsFromForm = resourceAttribute.IsFromForm;
+                    }
                     model.Code = requestXmlDoc?.Name;
                     model.Name = $"{model.ControllerSummary}-{model.ActionSummary}";
                     model.AllowAnonymous = resourceAttribute.AllowAnonymous;
@@ -181,9 +113,9 @@
                         model.ResponseTypeName = responseType.GetCSharpFriendlyName();
                         model.ResponseTypeFullName = responseType.FullName;
                     }
-
-
                     models.Add(model);
+
+                    await App.GetRequiredService<IDistributedCache>().SetStringAsync($"ResourceModel|{model.RequestTypeFullName}", model.ToJson());
                 }
             }
 
@@ -237,8 +169,7 @@
             var expiredResources = resources.Where(it => !models.Any(m => m.Route == it.Route && m.Method == it.Method)).ToList();
             foreach (var expiredResource in expiredResources)
             {
-                //expiredResource.IsExpired = true;
-                //await rep.UpdateAsync(expiredResource);
+                resources.Remove(expiredResource);
                 await rep.DeleteAsync(expiredResource);
             }
 
@@ -253,7 +184,21 @@
         public static void DynamicControllersHotPlug(List<Resource> resources, IDynamicApiRuntimeChangeProvider provider = null)
         {
             provider = provider ?? App.GetRequiredService<IDynamicApiRuntimeChangeProvider>();
-            foreach (var resource in resources)
+            var controllers = resources
+                .GroupBy(it => new
+                {
+                    it.ApplicationName,
+                    it.ControllerName,
+                    it.ControllerSummary,
+                    it.RouteArea
+                })
+                .Select(it => new
+                {
+                    it.Key,
+                    Actions = it.ToList()
+                })
+                .ToList();
+            foreach (var controller in controllers)
             {
                 var code = $@"
 using FlexJobApi.Core;
@@ -267,40 +212,70 @@
 using System.Collections.Generic;
 using System.ComponentModel;
 
-namespace {resource.ApplicationName}.{resource.Controller}.{resource.ActionName}Request
+
+namespace {controller.Key.ApplicationName}.{controller.Key.ControllerName}
 {{
     /// <summary>
-    /// {resource.ControllerSummary}
+    /// {controller.Key.ControllerSummary}
     /// </summary>
-    [Route(""api/{resource.RouteArea}/[controller]"")]
-    public class {resource.Controller}AppService(IMediator mediator) : IDynamicApiController
+    [Route(""api/{controller.Key.RouteArea}/[controller]"")]
+    public class {controller.Key.ControllerName}AppService(IMediator mediator) : IDynamicApiController
     {{
-        private readonly IMediator mediator = mediator;
+        private readonly IMediator mediator = mediator;";
+
+                foreach (var action in controller.Actions)
+                {
+                    var result = action.ResponseTypeName.IsNull() ? "Task" : $"Task<{action.ResponseTypeName}>";
+                    code += @$"
 
         /// <summary>
-        /// {resource.ActionSummary}
+        /// {action.ActionSummary}
         /// </summary>
         /// <param name=""request""></param>
         /// <returns></returns>";
-                if (resource.AllowAnonymous)
-                {
-                    code += $@"
+                    if (action.AllowAnonymous)
+                    {
+                        code += $@"
         [AllowAnonymous]";
-                }
-                code += $@"
-        [Http{resource.Method}]
-        public Task<{resource.ResponseTypeName}> {resource.ActionName}({resource.RequestTypeName} request)
+                    }
+                    code += $@"
+        [Http{action.Method}]";
+                    if (action.FileUpload)
+                    {
+                        code += @"
+        [Consumes(""multipart/form-data"")]";
+                    }
+                    code += @$"
+        public {result} {action.ActionName}(";
+                    if (action.FileUpload || action.IsFromForm)
+                    {
+                        code += "[FromForm] ";
+                    }
+                    code += $@"{action.RequestTypeName} request)
         {{
             return mediator.Send(request);
-        }}
+        }}";
+                }
 
-    }}
-}}
+                code += @"
+    }
+}
 ";
-                var dynamicAssembly = App.CompileCSharpClassCode(code);
-                provider.AddAssembliesWithNotifyChanges(dynamicAssembly);
-                var dynamicAssemblyName = dynamicAssembly.GetName().Name;
-                resource.DynamicAssemblyName = dynamicAssemblyName;
+                try
+                {
+                    var dynamicAssembly = App.CompileCSharpClassCode(code);
+                    provider.AddAssembliesWithNotifyChanges(dynamicAssembly);
+                    var dynamicAssemblyName = dynamicAssembly.GetName().Name;
+                    foreach (var action in controller.Actions)
+                    {
+                        action.DynamicAssemblyName = dynamicAssemblyName;
+                    }
+                }
+                catch (Exception ex)
+                {
+                    code.LogError(ex);
+                    throw;
+                }
             }
 
         }

--
Gitblit v1.9.1