- 为全部 5 个项目(Avalonia-API、Avalonia-Common、Avalonia-EFCore、 Avalonia-PC、Avalonia-Services)中缺失注释的类、方法、属性、字段、 接口成员等补全中文 XML 文档注释 - 共修改约 37 个文件,补全约 220+ 处注释 - 修复 ServiceEndpointCollection.cs 中 MapDelete<TService> 语法错误 - 修复 PcAuthService.cs 中 const prefix 位置错乱导致编译失败的问题 - 扫描结果:缺失项 0 - 构建结果:4/4 项目编译通过
148 lines
6.0 KiB
C#
148 lines
6.0 KiB
C#
using Avalonia_Common.Core;
|
||
using Avalonia_EFCore.Database;
|
||
using Avalonia_EFCore.Models;
|
||
using Avalonia_Services.Core;
|
||
using Avalonia_Services.Services;
|
||
using Microsoft.EntityFrameworkCore;
|
||
|
||
namespace Avalonia_Services.Endpoints
|
||
{
|
||
/// <summary>
|
||
/// 统一端点配置 —— 所有业务端点在此定义一次。
|
||
/// 这是 Avalonia-API 和 Avalonia-PC 的唯一入口。
|
||
/// </summary>
|
||
public static class AppEndpoints
|
||
{
|
||
/// <summary>
|
||
/// 配置所有业务端点。调用方传入 builder,按需叠加鉴权、过滤器等。
|
||
/// </summary>
|
||
/// <param name="builder">端点构建器</param>
|
||
/// <param name="includeDetails">是否在错误响应中包含异常详情(开发环境 true)</param>
|
||
public static ServiceEndpointBuilder Configure(ServiceEndpointBuilder builder, bool includeDetails = false)
|
||
{
|
||
// ---- 全局异常拦截(自动捕获所有端点中未处理的异常) ----
|
||
builder.Endpoints.AddGlobalFilter(new GlobalExceptionFilter(includeDetails));
|
||
|
||
builder.ConfigureEndpoints(endpoints =>
|
||
{
|
||
// ---- 全局日志过滤器(记录每个请求) ----
|
||
endpoints.AddGlobalFilter(async (ctx, next) =>
|
||
{
|
||
Serilog.Log.Debug("→ {Method} {Path}", ctx.Method, ctx.Path);
|
||
await next(ctx);
|
||
Serilog.Log.Debug("← {Method} {Path} | {StatusCode}", ctx.Method, ctx.Path, ctx.StatusCode);
|
||
});
|
||
|
||
// ---- 业务端点注册 ----
|
||
// 天气预报(从数据库读取)
|
||
endpoints.MapGet("api/wData", GetWeatherForecastsAsync)
|
||
.WithOpenApi("Weather", "获取天气预报信息。")
|
||
.WithName("GetWeatherForecast");
|
||
|
||
// 获取用户(演示从数据库查询)
|
||
endpoints.MapGet("api/getUser", GetUserFromDatabaseAsync)
|
||
.WithName("GetUser");
|
||
|
||
// 处理数据(POST — 演示参数处理)
|
||
endpoints.MapPost("api/processData", ProcessDataAsync)
|
||
.WithName("ProcessData");
|
||
|
||
// ---- 需要鉴权的端点示例 ----
|
||
// endpoints.MapGet("api/admin/dashboard", AdminDashboardAsync)
|
||
// .WithName("AdminDashboard")
|
||
// .RequireAuthorization = true
|
||
// .Policy = "AdminOnly";
|
||
|
||
});
|
||
|
||
return builder;
|
||
}
|
||
|
||
#region 业务处理方法
|
||
|
||
/// <summary>
|
||
/// 从数据库查询天气预报(优先数据库,回退到内存生成)。
|
||
/// </summary>
|
||
private static async Task<object?> GetWeatherForecastsAsync(ServiceEndpointContext ctx)
|
||
{
|
||
var sp = ctx.Items["ServiceProvider"] as IServiceProvider;
|
||
|
||
// 尝试从数据库读取
|
||
if (sp?.GetService(typeof(AppDataContext)) is AppDataContext db)
|
||
{
|
||
var dbForecasts = await db.WeatherForecasts
|
||
.OrderByDescending(f => f.Date)
|
||
.Take(5)
|
||
.ToListAsync();
|
||
|
||
if (dbForecasts.Count > 0)
|
||
{
|
||
return ResponseHelper.Ok(dbForecasts, "获取天气预报成功(来自数据库)");
|
||
}
|
||
}
|
||
|
||
// 回退:内存生成(数据库为空时)
|
||
var service = sp?.GetService(typeof(WeatherForecastService)) as WeatherForecastService
|
||
?? new WeatherForecastService();
|
||
|
||
var forecasts = service.GetWeatherForecasts();
|
||
return ResponseHelper.Ok(forecasts, "获取天气预报成功(内存生成)");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从数据库获取用户信息(演示数据库查询),若无数据则返回演示用户。
|
||
/// </summary>
|
||
/// <param name="ctx">服务端点上下文。</param>
|
||
/// <returns>用户信息。</returns>
|
||
private static async Task<object?> GetUserFromDatabaseAsync(ServiceEndpointContext ctx)
|
||
{
|
||
var sp = ctx.Items["ServiceProvider"] as IServiceProvider;
|
||
|
||
// 尝试从数据库读取用户
|
||
if (sp?.GetService(typeof(AppDataContext)) is AppDataContext db)
|
||
{
|
||
var users = await db.Set<UserEntity>().Take(1).ToListAsync();
|
||
if (users.Count > 0)
|
||
{
|
||
return ResponseHelper.Ok(users[0], "获取用户成功(来自数据库)");
|
||
}
|
||
}
|
||
|
||
// 回退:演示数据
|
||
await Task.Delay(100);
|
||
var user = new { id = 1, name = "张三", email = "zhangsan@example.com" };
|
||
return ResponseHelper.Ok(user);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理前端发送的数据(POST 演示),将数据存入数据库或转为大写返回。
|
||
/// </summary>
|
||
/// <param name="ctx">服务端点上下文。</param>
|
||
/// <returns>处理结果。</returns>
|
||
private static async Task<object?> ProcessDataAsync(ServiceEndpointContext ctx)
|
||
{
|
||
var sp = ctx.Items["ServiceProvider"] as IServiceProvider;
|
||
|
||
// 演示:将收到的数据存入数据库
|
||
var input = ctx.Body ?? string.Empty;
|
||
if (sp?.GetService(typeof(AppDataContext)) is AppDataContext db && !string.IsNullOrWhiteSpace(input))
|
||
{
|
||
var forecast = new WeatherForecastEntity
|
||
{
|
||
Date = DateOnly.FromDateTime(DateTime.Now),
|
||
TemperatureC = 20,
|
||
Summary = input,
|
||
};
|
||
db.WeatherForecasts.Add(forecast);
|
||
await db.SaveChangesAsync();
|
||
return ResponseHelper.Ok(forecast, "数据已存入数据库");
|
||
}
|
||
|
||
await Task.Delay(200);
|
||
return ResponseHelper.Ok(new { input, processed = input.ToUpperInvariant() });
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
}
|