sunpengfei
2025-08-04 4950d547503c7c1d5d0ff6487e6768937170ddf7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
using Furion;
using Furion.DatabaseAccessor;
using Furion.DistributedIDGenerator;
using Mapster;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
 
namespace FlexJobApi.Core
{
    /// <summary>
    /// 资源工具
    /// </summary>
    public static class ResourceUtils
    {
        /// <summary>
        /// 生成资源
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static async Task BuildWebApis(CancellationToken cancellationToken = default)
        {
            var traceId = App.GetTraceId() ?? IDGen.NextID().ToString();
            var scopeFactory = App.GetService<IServiceScopeFactory>();
            var serviceScope = scopeFactory.CreateScope();
            var rep = serviceScope.ServiceProvider.GetRequiredService<IRepository<Resource>>();
            var endpointDataSource = App.GetService<EndpointDataSource>();
            var routeEndpoints = endpointDataSource.Endpoints.OfType<RouteEndpoint>();
            var xmlDoc = await XmlDocUtils.GetXmlDocAsync();
            var enumWebApiMethods = await EnumUtils.GetModel<EnumWebApiMethod>();
            var webApis = await rep.AsQueryable().ToListAsync();
            foreach (var routeEndpoint in routeEndpoints)
            {
                var model = new ResourceModel();
                model.TraceId = traceId;
                model.Route = "/" + routeEndpoint.RoutePattern.RawText;
                var controllerActionDescriptor = routeEndpoint.Metadata.GetMetadata<ControllerActionDescriptor>();
                var methodInfo = controllerActionDescriptor.MethodInfo;
                var methodInfoXmlDoc = await controllerActionDescriptor.MethodInfo.GetXmlDocMemberAsync(xmlDoc);
                var controllerTypeXmlDoc = await methodInfo.DeclaringType?.GetXmlDocMemberAsync();
                model.Code = methodInfoXmlDoc.Name;
                model.Service = methodInfo.Module.Name.Split(".")[1];
                model.Method = enumWebApiMethods.GetEnum((controllerActionDescriptor.ActionConstraints[0] as HttpMethodActionConstraint).HttpMethods.FirstOrDefault());
                model.Name = $"{controllerTypeXmlDoc?.Summary ?? "没写注释"}-{methodInfoXmlDoc?.Summary ?? "没写注释"}";
                model.RequestTypeName = methodInfo.GetParameters().FirstOrDefault().ParameterType.FullName;
                var returnType = methodInfo.ReturnType;
                if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>))
                    returnType = returnType.GetGenericArguments()[0];
                if (returnType != null && returnType != typeof(Task))
                    model.ResponseTypeName = methodInfo.ReturnType.FullName;
 
                var webApi = webApis.FirstOrDefault(it => it.Route == model.Route && it.Method == model.Method);
                if (webApi == null)
                {
                    webApi = new Resource();
                    model.Adapt(webApi);
                    await rep.InsertAsync(webApi);
                    webApis.Add(webApi);
                }
                else
                {
                    model.Adapt(webApi);
                    await rep.UpdateAsync(webApi);
                }
            }
            var expiredWebApis = webApis.Where(it => it.TraceId != traceId).ToList();
            foreach (var webApi in expiredWebApis)
            {
                webApi.IsExpired = true;
                await rep.UpdateAsync(webApi);
            }
 
            await rep.SaveNowAsync();
        }
    }
}