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