luoqian 271e9714ff 统一服务端点架构,支持多端接口与数据库切换
重构项目结构,引入 Avalonia-Common、Avalonia-EFCore、Avalonia-Services,实现 API 与桌面端统一端点注册、过滤器、鉴权和标准响应格式。支持多数据库自动迁移与配置,集成 Serilog 日志系统。移除旧路由与控制器,提升接口一致性与可维护性。
2026-05-11 14:35:34 +08:00

177 lines
5.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Text.Json.Serialization;
namespace Avalonia_Common.Core
{
/// <summary>
/// 统一 API 返回格式。
/// 所有接口的返回都包装为此格式,确保前端收到一致的数据结构。
/// </summary>
/// <typeparam name="T">业务数据类型</typeparam>
public class ApiResponse<T>
{
/// <summary>是否成功</summary>
[JsonPropertyName("success")]
public bool Success { get; set; }
/// <summary>HTTP 状态码</summary>
[JsonPropertyName("code")]
public int Code { get; set; }
/// <summary>消息(成功时可为 null失败时包含错误描述</summary>
[JsonPropertyName("message")]
public string? Message { get; set; }
/// <summary>业务数据</summary>
[JsonPropertyName("data")]
public T? Data { get; set; }
/// <summary>时间戳</summary>
[JsonPropertyName("timestamp")]
public DateTime Timestamp { get; set; } = DateTime.Now;
/// <summary>请求追踪 ID用于排查问题</summary>
[JsonPropertyName("traceId")]
public string? TraceId { get; set; }
// ---- 快捷工厂方法 ----
/// <summary>成功返回(有数据)</summary>
public static ApiResponse<T> Ok(T data, string? message = null)
{
return new ApiResponse<T>
{
Success = true,
Code = 200,
Message = message,
Data = data,
};
}
/// <summary>失败返回</summary>
public static ApiResponse<T> Fail(int code, string message, T? data = default)
{
return new ApiResponse<T>
{
Success = false,
Code = code,
Message = message,
Data = data,
};
}
/// <summary>400 参数错误</summary>
public static ApiResponse<T> BadRequest(string message = "参数错误")
=> Fail(400, message);
/// <summary>401 未授权</summary>
public static ApiResponse<T> Unauthorized(string message = "未授权")
=> Fail(401, message);
/// <summary>403 无权限</summary>
public static ApiResponse<T> Forbidden(string message = "无权限")
=> Fail(403, message);
/// <summary>404 未找到</summary>
public static ApiResponse<T> NotFound(string message = "资源不存在")
=> Fail(404, message);
/// <summary>500 服务器内部错误</summary>
public static ApiResponse<T> ServerError(string message = "服务器内部错误")
=> Fail(500, message);
}
/// <summary>
/// 无数据的统一返回格式object? 版本)。
/// </summary>
public class ApiResponse : ApiResponse<object?>
{
/// <summary>成功返回(无数据)</summary>
public static ApiResponse Succeed(string? message = null)
{
return new ApiResponse
{
Success = true,
Code = 200,
Message = message,
Data = null,
};
}
/// <summary>失败返回</summary>
public static ApiResponse Failure(int code, string message)
{
return new ApiResponse
{
Success = false,
Code = code,
Message = message,
Data = null,
};
}
}
/// <summary>
/// 分页返回格式
/// </summary>
public class PagedResponse<T>
{
[JsonPropertyName("success")]
public bool Success { get; set; } = true;
[JsonPropertyName("code")]
public int Code { get; set; } = 200;
[JsonPropertyName("items")]
public List<T> Items { get; set; } = new();
[JsonPropertyName("total")]
public int Total { get; set; }
[JsonPropertyName("page")]
public int Page { get; set; } = 1;
[JsonPropertyName("pageSize")]
public int PageSize { get; set; } = 20;
[JsonPropertyName("totalPages")]
public int TotalPages => PageSize > 0 ? (int)Math.Ceiling((double)Total / PageSize) : 0;
public static PagedResponse<T> From(List<T> items, int total, int page, int pageSize)
{
return new PagedResponse<T>
{
Items = items,
Total = total,
Page = page,
PageSize = pageSize,
};
}
}
/// <summary>
/// 端点返回辅助方法 —— 在 AppEndpoints 中快捷构建统一响应。
/// </summary>
public static class ResponseHelper
{
/// <summary>成功返回</summary>
public static ApiResponse<T> Ok<T>(T data, string? message = null)
=> ApiResponse<T>.Ok(data, message);
/// <summary>成功返回(无数据)</summary>
public static ApiResponse Succeed(string? message = null)
=> ApiResponse.Succeed(message);
/// <summary>失败返回</summary>
public static ApiResponse<T> Fail<T>(int code, string message, T? data = default)
=> ApiResponse<T>.Fail(code, message, data);
/// <summary>失败返回(无数据)</summary>
public static ApiResponse Failure(int code, string message)
=> ApiResponse.Failure(code, message);
/// <summary>分页返回</summary>
public static PagedResponse<T> Paged<T>(List<T> items, int total, int page, int pageSize)
=> PagedResponse<T>.From(items, total, page, pageSize);
}
}