using System.Text.Json.Serialization;
namespace MAX.Framework.Dtos
{
public static class ResultCode
{
public const int Success = 200;
public const int Fail = 500;
public const int Unauthorized = 401;
public const int Forbidden = 403;
public const int NotFound = 404;
///
/// 参数校验失败
///
public const int ValidationError = 1001;
///
/// 业务逻辑异常
///
public const int BusinessError = 2001;
///
/// 服务器内部错误
///
public const int ServerError = 5000;
}
///
/// 非泛型基类,用于统一处理
///
public abstract class ApiResultBase
{
/// 业务状态码
public int Code { get; init; } = ResultCode.Success;
/// 提示信息
public string? Msg { get; init; }
/// 失败请求的跟踪标识,用于关联服务器日志。
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? TraceId { get; init; }
/// 请求是否成功
public bool Success => Code == ResultCode.Success;
}
///
/// 泛型响应
///
public class ApiResult : ApiResultBase
{
/// 响应数据;失败时不应依赖该值,值类型默认值并非 null。
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public T? Data { get; init; }
/// 将无数据响应转换为当前数据类型,保留状态码和提示信息。
public static implicit operator ApiResult(ApiResult result)
{
ArgumentNullException.ThrowIfNull(result);
return new ApiResult { Code = result.Code, Msg = result.Msg, TraceId = result.TraceId, Data = default };
}
public static ApiResult Ok(T data, string msg = "操作成功")
=> new ApiResult { Code = ResultCode.Success, Data = data, Msg = msg };
public static ApiResult Fail(string msg = "操作失败", int code = ResultCode.Fail, T? data = default)
{
ApiResult.ValidateFailureCode(code);
return new ApiResult { Code = code, Msg = msg, Data = data };
}
}
///
/// 响应
///
public class ApiResult : ApiResultBase
{
/// 无数据响应仍输出 data: null,保持统一的响应字段。
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public object? Data => null;
/// 创建带数据的成功响应,自动推断数据类型。
public static ApiResult Ok(T data, string msg = "操作成功")
=> ApiResult.Ok(data, msg);
/// 创建带数据的失败响应,自动推断数据类型。
public static ApiResult Fail(string msg, T data, int code = ResultCode.Fail)
=> ApiResult.Fail(msg, code, data);
public static ApiResult Ok()
=> new ApiResult { Code = ResultCode.Success, Msg = "操作成功" };
public static ApiResult Fail(string msg = "操作失败", int code = ResultCode.Fail, string? traceId = null)
{
ValidateFailureCode(code);
return new ApiResult { Code = code, Msg = msg, TraceId = traceId };
}
internal static void ValidateFailureCode(int code)
{
if (code == ResultCode.Success)
throw new ArgumentOutOfRangeException(nameof(code), code, "失败响应不能使用成功状态码。");
}
}
}