Files
TakeoutSaaS.TenantApi/src/Core/TakeoutSaaS.Shared.Abstractions/Results/ApiResponse.cs

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