using System; using System.Diagnostics; using TakeoutSaaS.Shared.Abstractions.Diagnostics; namespace TakeoutSaaS.Shared.Abstractions.Results; /// /// 统一的 API 返回结果包装。 /// /// 数据载荷类型 public sealed record class ApiResponse { /// /// 是否成功。 /// public bool Success { get; init; } /// /// 状态/错误码(默认 200)。 /// public int Code { get; init; } = 200; /// /// 提示信息。 /// public string? Message { get; init; } /// /// 业务数据。 /// public T? Data { get; init; } /// /// 错误详情(如字段验证错误)。 /// public object? Errors { get; init; } /// /// TraceId,便于链路追踪。 /// public string TraceId { get; init; } = string.Empty; /// /// 时间戳(UTC)。 /// public DateTime Timestamp { get; init; } = DateTime.UtcNow; /// /// 成功返回。 /// public static ApiResponse Ok(T data, string? message = "操作成功") => Create(true, 200, message, data); /// /// 无数据的成功返回。 /// public static ApiResponse Ok(string? message = "操作成功") => Create(true, 200, message, default); /// /// 兼容旧名称:成功结果。 /// public static ApiResponse SuccessResult(T data, string? message = "操作成功") => Ok(data, message); /// /// 错误返回。 /// public static ApiResponse Error(int code, string message, object? errors = null) => Create(false, code, message, default, errors); /// /// 兼容旧名称:失败结果。 /// public static ApiResponse Failure(int code, string message) => Error(code, message); /// /// 附加错误详情。 /// public ApiResponse WithErrors(object? errors) => this with { Errors = errors }; private static ApiResponse Create(bool success, int code, string? message, T? data, object? errors = null) => new() { Success = success, Code = code, Message = message, Data = data, Errors = errors, TraceId = ResolveTraceId(), Timestamp = DateTime.UtcNow }; private static string ResolveTraceId() { if (!string.IsNullOrWhiteSpace(TraceContext.TraceId)) { return TraceContext.TraceId!; } return Activity.Current?.Id ?? Guid.NewGuid().ToString("N"); } }