using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; namespace Avalonia_Services.Core { [Flags] public enum EndpointHostTarget { Api = 1, Pc = 2, All = Api | Pc, } /// /// 单个端点定义。 /// public class ServiceEndpoint { /// 路由路径,如 "api/wData" public string Pattern { get; init; } = string.Empty; /// HTTP 方法(GET/POST/PUT/DELETE) public string HttpMethod { get; init; } = "GET"; /// 端点名称(用于 OpenAPI / 日志) public string? Name { get; set; } /// OpenAPI 分组标签。 public string? OpenApiTag { get; set; } /// OpenAPI 摘要。 public string? OpenApiSummary { get; set; } /// OpenAPI 描述。 public string? OpenApiDescription { get; set; } /// OpenAPI 请求体类型。 public Type? OpenApiRequestType { get; set; } /// OpenAPI 200 响应数据类型。 public Type? OpenApiResponseType { get; set; } /// 端点处理器 public Func> Handler { get; init; } = _ => Task.FromResult(null); /// 该端点专属的过滤器(按顺序执行) public List Filters { get; init; } = new(); /// 是否需要鉴权 public bool RequireAuthorization { get; set; } /// 鉴权策略名 public string? Policy { get; set; } /// 允许访问该端点的角色。多个角色满足任意一个即可。 public List Roles { get; } = new(); /// 端点挂载的宿主。默认 API 和 PC 都挂载。 public EndpointHostTarget HostTarget { get; set; } = EndpointHostTarget.All; /// /// 设置端点名称(Fluent API)。 /// public ServiceEndpoint WithName(string name) { Name = name; return this; } public ServiceEndpoint WithOpenApi( string tag, string summary, string? description = null, Type? requestType = null, Type? responseType = null) { OpenApiTag = tag; OpenApiSummary = summary; OpenApiDescription = description; OpenApiRequestType = requestType; OpenApiResponseType = responseType; return this; } /// /// 标记端点需要登录。 /// public ServiceEndpoint RequireAuth() { RequireAuthorization = true; return this; } /// /// 标记端点需要指定角色。多个角色满足任意一个即可。 /// public ServiceEndpoint RequireRoles(params string[] roles) { RequireAuthorization = true; Roles.Clear(); Roles.AddRange(roles.Where(role => !string.IsNullOrWhiteSpace(role)).Select(role => role.Trim())); return this; } /// /// 只挂载到 Avalonia-API。 /// public ServiceEndpoint ApiOnly() { HostTarget = EndpointHostTarget.Api; return this; } /// /// 只挂载到 Avalonia-PC。 /// public ServiceEndpoint PcOnly() { HostTarget = EndpointHostTarget.Pc; return this; } public bool SupportsHost(EndpointHostTarget host) { return (HostTarget & host) != 0; } } /// /// 端点集合 —— 所有端点的注册中心。在 Avalonia-Services 中统一配置。 /// public class ServiceEndpointCollection { /// 所有已注册的端点 public List Endpoints { get; } = new(); public IEnumerable ForHost(EndpointHostTarget host) { return Endpoints.Where(endpoint => endpoint.SupportsHost(host)); } /// 作用于所有端点的全局过滤器 public List GlobalFilters { get; } = new(); /// /// 注册一个端点。 /// public ServiceEndpoint MapGet(string pattern, Func> handler) { return AddEndpoint(pattern, "GET", handler); } public ServiceEndpoint MapGet( string pattern, Func> handler) where TService : notnull { return MapGet(pattern, CreateServiceHandler(handler)); } /// /// 注册一个 POST 端点。 /// public ServiceEndpoint MapPost(string pattern, Func> handler) { return AddEndpoint(pattern, "POST", handler); } public ServiceEndpoint MapPost( string pattern, Func> handler) where TService : notnull { return MapPost(pattern, CreateServiceHandler(handler)); } /// /// 注册一个 PUT 端点。 /// public ServiceEndpoint MapPut(string pattern, Func> handler) { return AddEndpoint(pattern, "PUT", handler); } public ServiceEndpoint MapPut( string pattern, Func> handler) where TService : notnull { return MapPut(pattern, CreateServiceHandler(handler)); } /// /// 注册一个 DELETE 端点。 /// public ServiceEndpoint MapDelete(string pattern, Func> handler) { return AddEndpoint(pattern, "DELETE", handler); } public ServiceEndpoint MapDelete( string pattern, Func> handler) where TService : notnull { return MapDelete(pattern, CreateServiceHandler(handler)); } /// /// 添加全局过滤器(作用于所有端点)。 /// public ServiceEndpointCollection AddGlobalFilter(IEndpointFilter filter) { GlobalFilters.Add(filter); return this; } /// /// 通过匿名函数添加全局过滤器。 /// public ServiceEndpointCollection AddGlobalFilter(Func filter) { GlobalFilters.Add(new AnonymousEndpointFilter(filter)); return this; } private ServiceEndpoint AddEndpoint(string pattern, string method, Func> handler) { var endpoint = new ServiceEndpoint { Pattern = pattern, HttpMethod = method, Handler = handler, }; Endpoints.Add(endpoint); return endpoint; } private static Func> CreateServiceHandler( Func> handler) where TService : notnull { return async ctx => { var serviceProvider = ctx.Items["ServiceProvider"] as IServiceProvider ?? throw new InvalidOperationException("ServiceProvider 未注入。"); await using var scope = serviceProvider.CreateAsyncScope(); var service = scope.ServiceProvider.GetRequiredService(); return await handler(service, ctx); }; } } /// /// 构建器 —— 提供 Fluent API 来配置所有端点。 /// public class ServiceEndpointBuilder { /// /// 端点集合 /// public ServiceEndpointCollection Endpoints { get; } = new(); /// /// 鉴权服务(默认匿名) /// public IAuthService AuthService { get; set; } = new AnonymousAuthService(); /// /// 配置端点(在此方法中调用 endpoints.MapGet 等)。 /// public ServiceEndpointBuilder ConfigureEndpoints(Action configure) { configure(Endpoints); return this; } /// /// 设置鉴权服务。 /// public ServiceEndpointBuilder UseAuthService(IAuthService authService) { AuthService = authService; return this; } /// /// 构建最终的端点集合。 /// public ServiceEndpointCollection Build() { return Endpoints; } } }