using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using Oms.Application.Dtos.Orders;
using Oms.Domain.OrdersAggregate.Consts;
using Oms.Domain.SystemAggregate.Consts;
namespace Oms.Application.Shared;
///
/// OMS 通用文档与展示辅助方法。
///
public static class OmsDocHelper
{
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNameCaseInsensitive = true
};
private static readonly JsonSerializerOptions SnapshotJsonOptions = new()
{
PropertyNameCaseInsensitive = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
///
/// 将页码规范为至少 1。
///
public static int NormalizePage(int page) => page <= 0 ? 1 : page;
///
/// 将每页条数规范为 1~200。
///
public static int NormalizePageSize(int pageSize) => pageSize <= 0 ? 20 : Math.Min(pageSize, 200);
///
/// 将默认 DateTime 转为 null。
///
public static DateTime? NullIfDefault(DateTime value) => value == default ? null : value;
///
/// 将库内 JSON 字符串转为 API 可输出的 CLR 对象(避免 JsonElement 被 Newtonsoft 序列化成 valueKind)。
///
public static object? DeserializeJsonObject(string? json)
{
if (string.IsNullOrWhiteSpace(json))
{
return null;
}
using var document = JsonDocument.Parse(json);
return ConvertJsonElement(document.RootElement);
}
///
/// 反序列化 JSON 字符串为指定类型。
///
public static T? DeserializeJson(string? json)
{
if (string.IsNullOrWhiteSpace(json))
{
return default;
}
return JsonSerializer.Deserialize(json, JsonOptions);
}
///
/// 将请求体中的动态 JSON(JsonElement / JToken / Dictionary 等)规范为可落库的 JSON 字符串。
///
public static string? SerializeJson(T? value)
{
if (value is null)
{
return null;
}
if (value is JsonElement element)
{
return element.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined
? null
: element.GetRawText();
}
if (value is JsonNode node)
{
return node.ToJsonString();
}
if (value is string text)
{
return string.IsNullOrWhiteSpace(text) ? null : text;
}
var typeName = value.GetType().FullName;
if (typeName is not null && typeName.StartsWith("Newtonsoft.Json.Linq.", StringComparison.Ordinal))
{
return value.ToString();
}
return JsonSerializer.Serialize(value, JsonOptions);
}
///
/// 序列化发布快照(忽略 null,避免写出旧兼容字段)。
///
public static string? SerializeSnapshotJson(T? value)
{
if (value is null)
{
return null;
}
return JsonSerializer.Serialize(value, SnapshotJsonOptions);
}
public static SalesProductRulesPublishSnapshotDto? DeserializeRulesSnapshot(string? json)
{
var snapshot = DeserializeJson(json);
PublishSnapshotNormalizer.NormalizeRulesSnapshot(snapshot);
return snapshot;
}
public static SalesProductPricePublishSnapshotDto? DeserializePriceSnapshot(string? json)
{
var snapshot = DeserializeJson(json);
PublishSnapshotNormalizer.NormalizePriceSnapshot(snapshot);
return snapshot;
}
private static object? ConvertJsonElement(JsonElement element) => element.ValueKind switch
{
JsonValueKind.Object => element.EnumerateObject()
.ToDictionary(property => property.Name, property => ConvertJsonElement(property.Value)),
JsonValueKind.Array => element.EnumerateArray()
.Select(ConvertJsonElement)
.ToList(),
JsonValueKind.String => element.GetString(),
JsonValueKind.Number => element.TryGetInt64(out var integer)
? integer
: element.GetDecimal(),
JsonValueKind.True => true,
JsonValueKind.False => false,
JsonValueKind.Null or JsonValueKind.Undefined => null,
_ => element.GetRawText()
};
///
/// 反序列化 JSON 字符串数组。
///
public static List DeserializeStringList(string? json) => JsonStringArrayHelper.Deserialize(json);
///
/// 将订单状态码转为中文名称。
///
public static string? GetOrderStatusName(string statusCode)
{
return statusCode switch
{
OrderStatusCodes.Draft => "草稿",
OrderStatusCodes.Predeclared => "已预报",
OrderStatusCodes.Received => "已收货",
OrderStatusCodes.PendingPayment => "待支付",
OrderStatusCodes.PendingShip => "待发货",
OrderStatusCodes.PendingOnline => "待上网",
OrderStatusCodes.Shipping => "运输中",
OrderStatusCodes.DeliverySuccess => "派送成功",
OrderStatusCodes.DeliveryFailed => "派送失败",
OrderStatusCodes.Problematic => "问题件",
OrderStatusCodes.Deleted => "已删除",
OrderStatusCodes.Claimed => "理赔件",
_ => statusCode
};
}
///
/// 将仓库类型码转为中文名称。
///
public static string GetWarehouseTypeName(string warehouseType)
{
return warehouseType switch
{
WarehouseTypeCodes.Main => "主仓",
WarehouseTypeCodes.Transit => "中转仓",
WarehouseTypeCodes.Return => "退货仓",
WarehouseTypeCodes.Other => "其他",
_ => warehouseType
};
}
}